模板规则处理 XSLT 1.0 与 2.0 的差异 [英] Difference in template rule processing XSLT 1.0 vs 2.0

查看:29
本文介绍了模板规则处理 XSLT 1.0 与 2.0 的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此站点上回答另一个 XSLT 问题时,我偶然发现了 XSLT 1.0 和 2.0 之间的区别,我不明白.谁能解释这里发生了什么,以及如何解决差异?
注意:我使用的是 XML Spy 版本 2011 sp1 (x64).

Answering another XSLT question on this site, I stumbled on a difference between XSLT 1.0 and 2.0 that I don't understand. Who can explain what is happening here, and how the difference may be resolved?
Note: I am using XML Spy version 2011 sp1 (x64).

我的输入 XML 是

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <Manager grade="10" id="26">
        <Employee id="1" grade="9"/>
        <Employee id="2" grade="8"/>
    </Manager>
    <Manager grade="10" id="27">
        <Employee id="3" grade="9"/>
        <Employee id="4" grade="8"/>
        <Employee id="5" grade="4"/>
    </Manager>
    <Manager grade="7" id="28">
        <Employee id="6" grade="8"/>
        <Employee id="7" grade="7"/>
        <Employee id="8" grade="6"/>
        <Employee id="9" grade="9"/>
    </Manager>
    <Manager grade="9" id="29">
        <Employee id="10" grade="9"/>
        <Employee id="11" grade="8"/>
        <Employee id="12" grade="7"/>
    </Manager>
</root>

我希望选择等级大于或等于经理等级的员工集合.为此,我编写了以下 1.0 转换:

I wish to select the set of Employees that have a grade larger than or equal to the managers grade. For this I wrote the following 1.0 transformation:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <root>
            <xsl:apply-templates select="root/Manager"/>
        </root>
    </xsl:template>

    <xsl:template match="Manager">
        <mgr>
            <managerId><xsl:value-of select="@id"/></managerId>
            <managerGrade><xsl:value-of select="@grade"/></managerGrade>
            <empsSelection>
                <xsl:copy-of select="Employee[@grade &gt;= ../@grade]"/>
            </empsSelection>
        </mgr>
    </xsl:template>
</xsl:stylesheet>

输出是预期的

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <mgr>
        <managerId>26</managerId>
        <managerGrade>10</managerGrade>
        <empsSelection/>
    </mgr>
    <mgr>
        <managerId>27</managerId>
        <managerGrade>10</managerGrade>
        <empsSelection/>
    </mgr>
    <mgr>
        <managerId>28</managerId>
        <managerGrade>7</managerGrade>
        <empsSelection>
            <Employee id="6" grade="8"/>
            <Employee id="7" grade="7"/>
            <Employee id="9" grade="9"/>
        </empsSelection>
    </mgr>
    <mgr>
        <managerId>29</managerId>
        <managerGrade>9</managerGrade>
        <empsSelection>
            <Employee id="10" grade="9"/>
        </empsSelection>
    </mgr>
</root>

但是当我将 XSLT 版本更改为 2.0(采用上面的样式表并将 stylesheet/@version 更改为 2.0)时,我得到了以下不同且意外的结果:

But when I change the XSLT version to 2.0 (take above stylesheet and change stylesheet/@version to 2.0), I get the below different and unexpected result:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <mgr>
        <managerId>26</managerId>
        <managerGrade>10</managerGrade>
        <empsSelection>
            <Employee id="1" grade="9"/>
            <Employee id="2" grade="8"/>
        </empsSelection>
    </mgr>
    <mgr>
        <managerId>27</managerId>
        <managerGrade>10</managerGrade>
        <empsSelection>
            <Employee id="3" grade="9"/>
            <Employee id="4" grade="8"/>
            <Employee id="5" grade="4"/>
        </empsSelection>
    </mgr>
    <mgr>
        <managerId>28</managerId>
        <managerGrade>7</managerGrade>
        <empsSelection>
            <Employee id="6" grade="8"/>
            <Employee id="7" grade="7"/>
            <Employee id="9" grade="9"/>
        </empsSelection>
    </mgr>
    <mgr>
        <managerId>29</managerId>
        <managerGrade>9</managerGrade>
        <empsSelection>
            <Employee id="10" grade="9"/>
        </empsSelection>
    </mgr>
</root>

这是为什么?应该如何更改样式表才能在 XSLT 1.0 和 2.0 版本中获得正确的结果?

Why is this and how should the stylesheet be changed in order to get the correct result in both XSLT 1.0 and 2.0 version?

推荐答案

我认为在 XSLT 2.0 中,默认情况下您将比较作为字符串,而在 XSLT 1.0 中,比较运算符首先将任何操作数转换为数字,然后再与 XSLT 2.0 进行比较你需要

I think with XSLT 2.0 you by default get comparison as strings while with XSLT 1.0 the comparison operator converts any operands to numbers first which are then compared so with XSLT 2.0 you need

<xsl:template match="Manager">
    <mgr>
        <managerId><xsl:value-of select="@id"/></managerId>
        <managerGrade><xsl:value-of select="@grade"/></managerGrade>
        <empsSelection>
            <xsl:copy-of select="Employee[number(@grade) &gt;= number(current()/@grade)]"/>
        </empsSelection>
    </mgr>
</xsl:template>

得到你想要的结果.当然,使用其他数字类型如 xs:integer(@grade) 也应该这样做.

to get the result you want. Of course using other number types like xs:integer(@grade) should do as well.

这篇关于模板规则处理 XSLT 1.0 与 2.0 的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆