XPath:所有同级节点的名称
我无法使XPath:所有同级节点的名称,xpath,siblings,Xpath,Siblings,我无法使以下同级轴工作 我有一个XML文档,如下所示。我尝试了类似于name(/T/p/q/following sibling::*[1]的方法。我知道name只会产生集合的第一个,但是,该表达式不会返回任何内容。我正在Ubuntu上使用xmlstarlet命令尝试XPath <T> <p><q> <a1>A</a1> <a2>A</a2> <a3>A</a3> <a4>A&l
以下同级轴
工作
我有一个XML文档,如下所示。我尝试了类似于name(/T/p/q/following sibling::*[1]
的方法。我知道name
只会产生集合的第一个,但是,该表达式不会返回任何内容。我正在Ubuntu上使用xmlstarlet
命令尝试XPath
<T>
<p><q>
<a1>A</a1>
<a2>A</a2>
<a3>A</a3>
<a4>A</a4>
<a5><b1>A</b1></a5>
</q></p>
</T>
事实上,这比你想象的要简单得多
/T/p/q/*
返回节点集a1、a2、a3、a4、a5
它选择q
的所有子节点,该子节点是p
的子节点,该子节点是T
的子节点,该子节点是上下文节点的子节点
说到“children”,我指的是“直系子代”,而不是“后代”。因此,它只会选择a1-a5
级别的节点
正如您所说,name()
函数只返回节点集中第一个节点的名称。我想您必须遍历节点集才能将所有名称作为单个字符串获取
使用xmlstarlet
,您可以执行以下操作:
xml sel -t -m "/T/p/q/*" -v "name(.)" -n input.xml
它匹配节点集,在其中的每个节点上调用name(.)
,然后打印一个换行符
-m
以匹配XPath表达式
-v
打印XPath表达式返回的值
-n
换行符
要使用following sibling
axis,您必须处于同一级别,例如,要选择a2
的所有后续同级,您需要使用/T/p/q/a2/following sibling::*
。这将返回a3、a4、a5
在XPath 1.0中,无法获得elemen所需的所有子级名称ts/T/p/q/*
通过计算单个XPath表达式。
因此,需要在第一步中选择所有元素:
/T/p/q/*
然后,对于结果XmlNodeList中包含的每个元素,一个新的XPath表达式(根据该元素计算)将生成其名称
对于XPath 1.0,可以使用不同的宿主语言实现该算法
下面是一个示例,其中XPath 1.0的宿主语言是XSLT 1.0:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:variable name="vWanted" select="/T/p/q/*"/>
<xsl:for-each select="$vWanted">
<xsl:value-of select="name()"/> <xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
II.单个XPath 2.0表达式-解决方案:
<T>
<p><q>
<a1>A</a1>
<a2>A</a2>
<a3>A</a3>
<a4>A</a4>
<a5><b1>A</b1></a5>
</q></p>
</T>
a1 a2 a3 a4 a5
/T/p/q/*/name()
对上述XPath 2.0表达式的求值将生成一个由五个项组成的序列,每个项都是不同的/T/p/q/*
元素的名称。谢谢,斯兰内克。我如何使用/T/p/q/*
只返回节点名称?name
函数将只返回第一个?至于您的后面的兄弟姐妹代码>例如,问题是,我事先不知道first(或任何)的名字q
的孩子。对不起,我之前没有澄清这一点。@Cogiotergosum我用一个完整的xmlstarlet
查询更新了答案,以获取所有的名字。谢谢你,斯兰内克!这很有帮助。@Dimitre Novatchev,我会使用你的解决方案。但是,我的要求是在SQL中为Derby数据库包装XPath(我刚才就这么做了)。无论如何,谢谢!@cogiotergosum,但是-接受的是Dimitre:)。无论如何,我很高兴我能帮上忙,那天我自己也遇到了一些麻烦。。。
/T/p/q/*/name()