使用local-name()在XSLT中获取第一个子节点



假设我们有这个简单的xml…

 <books>   
    <book>
       <author/>
       <title/>
    </book>
    <book>
       <author/>
       <title/>
    </book>
 </books>

我使用这个xpath来获取第一个book实例的元素。

//books[1]/*

返回
<author/>
<title/>

这工作得很好,但我必须让它使用local-name()工作。我试过以下方法,但都不起作用…

//*[local-name()='books']/*

返回重复的author和title元素,不太好,我只需要它们来自第一个子元素

//*[local-name()='books'][0]/*

这个不返回任何东西

基本上,我想创建一个CSV文件,因此输出中的第一行将是一个标头,列出图书属性名,后跟任意数据值。我只需要让标题部分工作。

author,title
john,The End is Near
sally,Looking for Answers

这是一个常见问题——XPath []操作符比//伪操作符具有更高的优先级(优先级)。

:

//someElemName[1]

选择父元素的第一个子元素someElemName——并且,根据XML文档的不同,可以有多个这样的元素。

要改变这个,必须使用括号。

使用

:

(//*[local-name() = 'book'])[1]/*

还要注意:在XPath中位置是基于1的,而不是基于0的。

基于xslt验证:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:template match="/">
  <xsl:copy-of select=
  "(//*[local-name() = 'book'])[1]/*"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下XML文档:

<books>
    <book num="1">
        <author num="1"/>
        <title num="1"/>
    </book>
    <book num="2">
        <author num="2"/>
        <title num="2"/>
    </book>
</books>

选择所需节点并复制到输出:

<author num="1"/>
<title num="1"/>

你说的路径表达式为你工作

//books[1]/*

生成第一次出现的所有子节点的列表(在这种情况下是唯一的)节点。因为,在您的数据中,唯一出现的位于根目录,它与

相同
/books/*

返回两个节点,所以你说它只返回一个节点是错误的。

很难知道您需要什么,因为如果您总是将local-name应用于根节点,那么您不需要知道它的名称,并且只需使用/*即可访问它,因此您只需

/*/*[1]

但是要访问

在文档的任何地方
//*[local-name()='books']/*[1]

您应该小心地尽可能限制上下文,因为以//开始XPath表达式将强制搜索整个文档,如果所讨论的节点总是在根节点上,那么这是毫无意义且耗时的。

我也有同样的顾虑。我的解决方法如下:

//*[local-name()='MYNODENAME' and position()=X]

祝你今天愉快。

相关内容

  • 没有找到相关文章

最新更新