xml 使用 local-name() 获取 XSLT 中的第一个子节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8058308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get first child node in XSLT using local-name()
提问by raffian
Assume we have this simple xml ...
假设我们有这个简单的 xml ...
<books>
<book>
<author/>
<title/>
</book>
<book>
<author/>
<title/>
</book>
</books>
I'm using this xpath to get the elements of the first book instance.
我正在使用这个 xpath 来获取第一个 book 实例的元素。
//books[1]/*
Returns
退货
<author/>
<title/>
And that works fine, but I have to get it working using local-name(). I've tried the following but none of these work...
这工作正常,但我必须使用 local-name() 让它工作。我已经尝试了以下但这些都不起作用......
//*[local-name()='books']/*
this returns repeating author and title elements, not good, I only need them from the first child
这将返回重复的作者和标题元素,不好,我只需要第一个孩子的它们
//*[local-name()='books'][0]/*
this does not return anything
这不会返回任何东西
Basically, I want to create a CSV file, so the first line in the output will be a header listing the book attribute names followed by the arbitrary data values. I only need to get the header part working.
基本上,我想创建一个 CSV 文件,因此输出中的第一行将是一个标题,列出书籍属性名称,后跟任意数据值。我只需要让标题部分工作。
author,title
john,The End is Near
sally,Looking for Answers
回答by Dimitre Novatchev
This is a FAQ-- the XPath []operator has higher precedence (priority) than the //pseudo-operator.
这是一个常见问题解答——XPath[]运算符比//伪运算符具有更高的优先级(优先级)。
So:
所以:
//someElemName[1]
selects every element named someElemNamethat is the first child of its parent -- and, depending on the XML document, there can be more than one such elements.
选择每个命名someElemName为其父元素的第一个子元素的元素——并且,根据 XML 文档,可以有多个这样的元素。
To change this, one must use brackets.
要改变这一点,必须使用括号。
Use:
使用:
(//*[local-name() = 'book'])[1]/*
Also note: In XPath positions are 1-based, not 0-based.
另请注意:在 XPath 中,位置是基于 1 的,而不是基于 0 的。
XSLT-based verification:
基于 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>
when this transformation is applied on the following XML document:
当此转换应用于以下 XML 文档时:
<books>
<book num="1">
<author num="1"/>
<title num="1"/>
</book>
<book num="2">
<author num="2"/>
<title num="2"/>
</book>
</books>
the wanted nodes are selected and copied to the output:
选择想要的节点并复制到输出:
<author num="1"/>
<title num="1"/>
回答by Borodin
The path expression you say works for you
你说的路径表达式适合你
//books[1]/*
generates a list of all child nodes of the first (and only in this case) occurrence of any <books> node. Because, in your data, the only occurrence of <books> is at the root, it is the same as
生成任何 <books> 节点的第一次(并且仅在这种情况下)出现的所有子节点的列表。因为,在您的数据中, <books> 唯一出现在根处,它与
/books/*
which returns two <book> nodes, and so you are wrong to say that it returns only one node.
它返回两个 <book> 节点,所以你说它只返回一个节点是错误的。
It is hard to know what you need, as if you are always applying local-nameto the root node then you do not need to know its name and can access it with just /*, so you would want simply
很难知道你需要什么,就好像你总是在申请local-name根节点,那么你不需要知道它的名字并且可以使用 just 来访问它/*,所以你只想要
/*/*[1]
However to access the first child node of a <books> node anywhere in the document you would write
但是,要访问文档中任意位置的 <books> 节点的第一个子节点,您将编写
//*[local-name()='books']/*[1]
You should be careful to confine your context as much as possible, as starting the XPath expression with //will force a search of the entire document, which is pointless and time-consuming if the node in question is always at the root.
您应该尽可能小心地限制您的上下文,因为 XPath 表达式开始时//将强制搜索整个文档,如果所讨论的节点始终位于根节点,这将毫无意义且耗时。
回答by I_am_an_invited_person
I have to meet same concerns. I solved as follows:
我必须满足同样的担忧。我解决如下:
//*[local-name()='MYNODENAME' and position()=X]
Have a nice day.
祝你今天过得愉快。

