xml - 匹配 XSL 中的子元素

标签 xml xslt xpath

我以为我在对 this question 的回答中看到了一个错误,并指出。有人告诉我我错了,后来我的答案被删除了。

我仍然不明白我错在哪里。因此,我在这里发帖,希望有人能向我解释我的误解。

我回复的回答说明了apply-templates的使用。它包含以下 XML 和 XSL,描述了模板将如何匹配:

<!-- sample XML snippet -->
<xml>
  <foo /><bar /><baz />
</xml>

<!-- sample XSLT snippet -->
<xsl:template match="xml">
  <xsl:apply-templates select="*" /> <!-- three nodes selected here -->
</xsl:template>

<xsl:template match="foo"> <!-- will be called once -->
  <xsl:text>foo element encountered</xsl:text>
</xsl:template>

<xsl:template match="xml/*"> <!-- will be called twice -->
  <xsl:text>other element countered</xsl:text>
</xsl:template>

我的意见是最后一个模板应该是:

<xsl:template match="*"> <!-- will be called twice -->
  <xsl:text>other element countered</xsl:text>
</xsl:template>

因为当前节点已经是<xml>

有人告诉我:

No, xml/* is a pattern that matches child elements of an element with the name xml.

测试原始答案

但是,对于这个 XML:

<xml>
  <foo /><bar /><baz />
</xml>

还有这个 XSL 样式表(填写上面的代码片段):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>

<xsl:template match="xml">
  <xsl:apply-templates select="*" /> <!-- three nodes selected here -->
</xsl:template>

<xsl:template match="foo"> <!-- will be called once -->
  <xsl:text>foo element encountered.&#xa;</xsl:text>
</xsl:template>

<xsl:template match="xml/*"> <!-- will be called twice -->
  <xsl:text>other element countered.&#xa;</xsl:text>
</xsl:template>

</xsl:stylesheet>

我得到:

other element countered.
other element countered.
other element countered.

测试我的“更正”版本

如果我将最后一个模板替换为:

<xsl:template match="*"> <!-- will be called twice -->
  <xsl:text>other element countered.&#xa;</xsl:text>
</xsl:template>

根据我的回答,我得到:

foo element encountered.
other element countered.
other element countered.

这似乎是正确的。

我希望我的问题没有违反任何准则,但我看不出我错了,希望有人能更全面地解释它。

附言。恐怕我对另一个问题的原始回复是作为答案而不是评论发布的,因为我还没有足够的积分来发表评论。我不确定最好的办法是什么...

最佳答案

根据rules on the default priority of templates,这是正确的.匹配foo的模板默认优先级为0,匹配*的模板默认优先级为-0.5,而匹配xml/*的模板默认优先级为0.5。 xml/* 模板被认为比 foo 模板更具体,因此当两者都匹配时它会获胜。

所以你是对的,模板的匹配表达式需要是 * 而不是 xml/*,但不是出于正确的原因 - xml/* 模板可以匹配一个apply-templates select="*",当当前节点是xml时,它将应用于这些选定元素中的任何一个(因为它们都是 xml 的子元素),除非有另一个模板具有大于 0.5 的显式 priority 可以优先。

关于xml - 匹配 XSL 中的子元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15868300/

相关文章:

python - 在 Python 中进行 XML 转换的现代方法是什么?

xml - 抓取分层数据

java - 如何根据 XSD 文件验证 XML 文件?

xml - 通过XPath获取所有冗余元素

xml - XSL value-of 似乎没有从 xml 中获取值

xml - 如何为一个节点使用两个不同的分析字符串

xml - 为什么 XML 文字在 Scala 中产生可变对象?

xml - XML 命名空间有什么用?

html - xpath在元素之后获取所有元素

xml - XSLT - 如何更改其值包含给定子字符串的任何属性的值