【问题标题】:Get first child node in XSLT using local-name()使用 local-name() 获取 XSLT 中的第一个子节点
【发布时间】:2011-12-24 21:22:59
【问题描述】:

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

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

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

//books[1]/*

返回

<author/>
<title/>

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

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

这会返回重复的作者和标题元素,不好,我只需要第一个孩子的他们

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

这不会返回任何东西

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

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

【问题讨论】:

  • 您的查询//books[1]/* 应该返回两个书籍元素,而不是作者和标题元素。所以有些地方有些混乱。
  • 不,它只返回第一个与我的 Xalan 1.0 XSLT 转换器
  • 是的,那是我在 OP 中的坏处,我使用的是基于 [1] 的,谢谢提供信息
  • @RaffiM:您是否知道您接受了一个通常不正确的答案这一事实?

标签: xml xslt xpath xslt-1.0 xalan


【解决方案1】:

你说的路径表达式对你有用

//books[1]/*

生成任何 节点的第一个(并且仅在这种情况下)出现的所有子节点的列表。因为,在您的数据中, 的唯一出现是在根部,它与

相同
/books/*

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

很难知道你需要什么,好像你总是将local-name应用于根节点,那么你不需要知道它的名字,只需/*就可以访问它,所以你想要简单

/*/*[1]

但是,在您要编写的文档中的任何位置访问 节点的第一个子节点

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

您应该尽可能小心地限制上下文,因为以 // 开头的 XPath 表达式将强制搜索整个文档,如果相关节点始终位于根。

【讨论】:

  • 请参阅我在原始帖子上方的编辑,以获取有关我正在尝试完成的工作的更多详细信息,对于缺少更多详细信息,我们深表歉意。我尝试使用 /*/*[1],它打印了两次“作者,标题”,我只需要打印一次。
【解决方案2】:

这是一个常见问题解答——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"/>

【讨论】:

  • @RaffiM:我的回答对你有用吗?
【解决方案3】:

我必须遇到同样的问题。我解决了如下:

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

祝你有美好的一天。

【讨论】:

    猜你喜欢
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    相关资源
    最近更新 更多