xslt 中的 xpath 产生与直接评估 xpath 不同的结果

Posted

技术标签:

【中文标题】xslt 中的 xpath 产生与直接评估 xpath 不同的结果【英文标题】:xpath within xslt yields different result from direct evaluation of xpath 【发布时间】:2016-11-22 13:18:15 【问题描述】:

我有这个简单的 xml 文档

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://example.org/attributes">
    <record>
        <codice_fiscale>IT07654930130</codice_fiscale>
        <indirizzo tipo="casa">Viale Carlo Espinasse 5, Como</indirizzo>
    </record>
    <n:record xmlns:n="http://test.com/records">
        <n:codice_fiscale>IT87654770157</n:codice_fiscale>
        <n:indirizzo tipo="ufficio">Via Biancospini 20, Messina</n:indirizzo>
    </n:record>
    <record>
        <codice_fiscale>IT471142131</codice_fiscale>
        <indirizzo tipo="ufficio">Via Chiasserini 88B, Firenze</indirizzo>
        <test>
            <nummeroo>01-000-000</nummeroo>
            <nummeroo>02-000-000</nummeroo>
        </test>
        <test>
            <nummeroo>03-000-000</nummeroo>
            <nummeroo>04-000-000</nummeroo>
        </test>
        <stuff>other stuff</stuff>
    </record>
    <things>
        <nummero>08-000-000</nummero>
        <nummero>09-000-000</nummero>
    </things>
</root>

以下 xslt 2.0 样式表应输出所有元素的名称,这些元素至少有一个叶节点作为子节点。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="no" />
    <xsl:strip-space elements="*"/>
    <xsl:template match="//*[child::*[not(*)]]">
        <xsl:value-of select="concat(name(), '&#xa;')" />
    </xsl:template>
</xsl:stylesheet>

我使用omit-xml-declaration 并去除所有空格以获得简单的文本文档。与'&amp;#xa;' 连接会给我一个换行符。

将 xslt 应用于上述 xml 文档会产生以下结果

record
n:record
record
things

在样式表中使用模板的 xpath 2.0 表达式,即

//*[child::*[not(*)]]

结合name()-函数将元素名称作为字符串获取,即

//*[child::*[not(*)]]/name()

我得到以下结果(使用不同的编辑器/xpath 2.0 评估器)

record
n:record
record
test
test
things

使用 xslt 2.0 样式表并使用编辑器直接评估 xpath 2.0 表达式会产生不同的结果!

我希望结果完全相同。样式表和 xpath //*[child::*[not(*)]]/name() 的直接评估本质上是相同的,并且应该提供相同的文本输出。

xpath 表达式和样式表非常简单,但我无法弄清楚为什么对两者的评估会产生不同的结果。

有人知道为什么这两个评估会产生不同的结果吗?

【问题讨论】:

【参考方案1】:

match 模式与 select 表达式不同。

你的样式表会发生什么:

首先,内置模板规则应用于/根节点。

然后,使用内置递归,将相同的内置模板应用于root 根元素。

接下来,您的模板将启动并处理作为根元素的子节点的节点 - 此处处理停止,因为您的模板不包含 xsl:apply-templates 指令。

请注意,匹配模式中会忽略前导 //

【讨论】:

感谢迈克尔的帮助解释。看来xslt我还是要学很多东西的。

以上是关于xslt 中的 xpath 产生与直接评估 xpath 不同的结果的主要内容,如果未能解决你的问题,请参考以下文章

优化 xslt xpath 匹配表达式

XSLT:测试当前元素是不是匹配变量 xpath

如何将 xslt 中的参数用作 XPath?

与 XPath 表达式相比,非流模式下的 XSLT 3 累加器是不是提供性能优势?

bash 中的 XSLT 转换将 XPATH 值传递给输出文件名

XML-XSLT-XPATH:如何获取重复记录?