Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XPath:所有同级节点的名称_Xpath_Siblings - Fatal编程技术网

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()