【问题标题】:xsl:key element in XSLT 2.0 Syntax questionXSLT 2.0 语法问题中的 xsl:key 元素
【发布时间】:2019-08-29 09:05:21
【问题描述】:

我使用xsl:key 元素和key() 函数的方式似乎不起作用。我的语法有问题吗?

在 W3Schools 上查找了元素和函数,但在我看来,我的语法与他们的一致。 https://www.w3schools.com/xml/func_key.asp https://www.w3schools.com/xml/ref_xsl_el_key.asp

我的 xml 示例

<?xml version="1.0" encoding="UTF-8"?>
<customerdatabase>
    <customer id="1" Shortname="Shortname1"/>
    <customer id="2" Shortname="Shortname2"/>
    <customer id="48412" Shortname="Shortname48412"/>
</customerdatabase>

我的 XSLT 示例

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:dn="myPersonalNamespace">
    <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>

    <xsl:key name="contents" match="/customerdatabase/customer" use="@id"/>

    <xsl:template name="MasterTemplate" match="customerdatabase">

        <xsl:result-document href="keyTest.xmi">
            <dn:Output xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:dn="myPersonalNamespace">
                <dn:Test1>
                    <xsl:for-each select="key('contents', 48412)">
                        <xsl:value-of select="@Shortname"/>
                    </xsl:for-each>
                </dn:Test1>
                <dn:Test2>
                    <xsl:value-of select="key('contents',1)/@Shortname"/>
                </dn:Test2>
                <dn:Test3>
                    <xsl:value-of select="key('contents',48412)/@Shortname"/>
                </dn:Test3>
            </dn:Output>
        </xsl:result-document>
    </xsl:template>
</xsl:stylesheet>

生成的 keyTest.xmi 文件已创建,但 Testx 元素为空。

【问题讨论】:

    标签: xml xslt xslt-2.0


    【解决方案1】:

    在 XSLT/XPath 2 和更高版本的类型系统中,您在调用中传递给键函数的值(如 key('contents', 48412))是 xs:integer 类型的文字,而您的键声明 use="@id",这将导致字符串值(在通常,属性的原子化值将是一个字符串,除非您使用模式感知 XSLT)用于构建键索引。因此,要么将声明更改为 use="xs:integer(@id)" 并且您的 key 调用应该有效,要么保留声明但将调用更改为使用字符串,例如key('contents', '48412').

    见https://www.w3.org/TR/xslt20/#xsl-key说

    如果存在 use 属性,它的值是一个表达式,指定 键的值。表达式将与节点一起评估 匹配模式作为上下文节点。评估结果 表达式被原子化了。

    和https://www.w3.org/TR/xslt20/#function-key

    key 函数的 $key-value 参数被认为是 顺序。请求的键值集合是通过原子化 提供的参数值,使用标准函数转换 规则。每个得到的原子值都被认为是 请求的键值。函数的结果是一个序列 节点,按文档顺序并删除重复项,包括那些 所选子树(见下文)中与 xsl:key 声明,其名称与提供的密钥名称相同, 其中评估键说明符的结果包含一个值 根据规则,等于这些请求的键值之一 适用于有问题的两个值的 XPath eq 运算符

    在 XSLT 1 中这有点不同,键值始终是字符串值,key 函数将参数转换为字符串,参见 https://www.w3.org/TR/xslt-10/#key 的说法:

    键的值(字符串)

    和https://www.w3.org/TR/xslt-10/#function-key

    当 key 函数的第二个参数是节点集类型时,那么 结果是应用关键函数的结果的并集 参数节点集中每个节点的字符串值。什么时候 key 的第二个参数是任何其他类型,参数是 就像通过调用字符串函数一样转换为字符串;它 返回一个节点集,其中包含与 具有与此字符串相等的命名键值的上下文节点

    【讨论】:

    • 非常感谢您快速、简单且信誉良好的回答。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    相关资源
    最近更新 更多