XSLT和for-each循环

时间:2014-02-08 17:34:29

标签: xslt

我在这里使用XML文件

http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml

我已经写了这段代码

  <xsl:for-each select="registry/record">

然而,由于XML中的这一行,它永远找不到任何东西

<registry xmlns="http://www.iana.org/assignments" id="service-names-port-numbers">

如果我将其更改为

<registry>

它工作正常但是我无法更改XML,我必须更改XSLT。我能做些什么才能让它发挥作用?我只需要找到那些记录。

感谢。

1 个答案:

答案 0 :(得分:0)

XSLT和XPath是名称空间感知的。不幸的是,他们没有为路径设置默认命名空间的任何表示法,因此您必须使用绑定到命名空间的显式前缀。

如果您不熟悉XML命名空间,请查看它们。他们很重要。

以您的具体示例为例,这是SNTP文档开头的简化版本

<registry xmlns="http://www.iana.org/assignments" id="service-names-port-numbers">
  <title>Service Name and Transport Protocol Port Number Registry</title>
  <category>Service Names and Transport Protocol Port Numbers</category>
  <updated>2014-02-06</updated>
  <xref type="rfc" data="rfc6335"/>
  <expert> ... names of experts ... </expert>
  <note> ... usage notes ... </note>
  <record>
    <protocol>tcp</protocol>
    <xref type="person" data="Jon_Postel"/>
    <description>Reserved</description>
    <number>0</number>
  </record>
</registry>

xmlns="http://www.iana.org/assignments"是默认的命名空间绑定。本文档中的所有元素都将位于该命名空间中,除非它们具有绑定到另一个命名空间的前缀或另一个xmlns=用于更改它们及其子节点的默认值。

您的XPath和匹配表达式必须引用此命名空间,否则它们将无效。

更改

 <xsl:for-each select="registry/record">

 <xsl:for-each select="assignments:registry/assignments:record"
   xmlns:assignments="http://www.iana.org/assignments">

(您可以使用比assignments更短的前缀;我只是想尽可能清楚地说明这一点。您还可以在XSLT文档中将前缀绑定在更高的位置 - 通常在{{1元素 - 因此它可以在整个样式表中使用,而不仅仅是在这一个地方。)

这将有效,假设您的其余代码是正确的。

另外:一般来说,<xsl:stylesheet>往往被滥用。一般情况下,除非您确实需要进行与样式表中其他任何位置不同的处理,否则您应该使用<xsl:for-each>,以便可以应用正常的模板匹配规则。否则,您将难以扩展和维护样式表。 XSL是一种规则匹配的非过程语言;学习以这种方式使用它。