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 - Fatal编程技术网

选择XPath中的第一个结果

选择XPath中的第一个结果,xpath,Xpath,我已经看了这个问题: 但如果我有这样一个节点集: <container value=""> <data id="1"></data> <data id="2">test</data> <container> <data id="1">test</data> <data id="3">test</data> </container>

我已经看了这个问题:

但如果我有这样一个节点集:


<container value="">
  <data id="1"></data>
  <data id="2">test</data>
  <container>
    <data id="1">test</data>
    <data id="3">test</data>
  </container>
</container>

测试
测试
测试
现在我的场景是,这个节点集位于文档的深处,我有一个指向内部容器的指针。因此,我必须在XPath前面加“/container/container”(路径实际上更长,但在本例中应该这样做)

编辑: 我想要的是一个id为1的“数据”节点,它应该首先来自最低的节点或最近的祖先。因此,如果我在“current”(/container/container)上找不到它,我应该查看祖先并得到最近的一个(或者最终什么也找不到)。我试过这个:

/容器/容器/祖先或self::容器/数据[@id=“1”]


这将返回一个包含两个节点的结果集。我想我可以用last()来得到最深的一个,所以我把它钉在了最后,但没有用。

我不是100%清楚你想要什么,但是如果我读对了,也许你只是想:

/container/container/ancestor-or-self::container[1]/data[@id='1']
请注意“[1]”

编辑:仔细考虑一下,下面的内容适用于目前为止寻找@id=$N的所有情况

/container/container/ancestor-or-self::container[data[@id=$N]][1]/data[@id=$N]
非常极端的体验。基本上,发生的是来自祖先或自我的节点集返回位置1处的最低顺序-这是您想要的-但您需要对其设置第二个条件,即节点也有您感兴趣的数据节点,一旦满足了这些条件,就有了正确的节点,现在您只需要进一步深入实际数据


如果将xpath分解并将其视为一种算法,99%的情况下xpath会变得更容易:)

您是如何尝试将last()添加到上的?我认为这应该奏效:

/container/container/ancestor-or-self::container/data[@id="1"][last()]
编辑:

对,当然,我忘了括号:

(/container/container/ancestor-or-self::container/data[@id="1"])[last()]
这与其他答案中的一个相同;然而,正如原始海报所指出的,这种表达在以下方面失败了:

<container value="">
  <container>
    <data id="1">a3</data>
    <data id="3">a4</data>
  </container>
  <data id="1">a1</data>
  <data id="2">a2</data>
</container>
顺便说一下,如果一个容器中有多个@id-is-1子容器,这将返回所有子容器。要仅返回第一个此类元素,请执行以下操作:

而不是

@id="1"
您是否尝试过:

position() == 1
确保
last()
的范围正确。尝试:

(/container/container/ancestor-or-self::container/data[@id="1"])[last()]
同样地:

//container[last()]
以及:

它们不是一回事。第一个将返回层次结构每个级别的最后一个容器节点(多个匹配项),第二个将返回找到的最后一个容器节点(一个匹配项)。

try [位置()=1]

/容器/容器/祖先或self::容器/数据[position()=1]


如果我在这里对所需结果的理解是正确的(大If),那么这将不起作用,因为最后一个()将在祖先或自我的两个分支上匹配-这是真正的问题,所以您需要提前(如我所做)或延迟(如Dave所做)剪裁结果集。这一个做到了。非常感谢(大家也一样)!该规范可以更加清晰。您想要数据节点吗?数据节点的id必须为1?形成原始容器如果数据节点的id不为1,则要将文档向上移动到父容器,以查看该容器是否具有id为1的数据节点,如果不继续,则直到找到id为1的数据节点为止。这说明了吗?我试图把我想要的描述得更清楚一点,尽管有些人猜到了。很抱歉如果position()==1可以工作,那么就一起删除祖先或self::all。我认为要求不只是任何第一个数据节点,而是id为1的数据节点。问题并没有那么清楚。事实上,我发现如果在匹配数据元素之前指定了子容器节点,则这种方法不起作用。@Nick Spacek-我改进了下面的答案,现在它甚至涵盖了那个角落的情况。我尝试过这样做,但并不涵盖所有情况。如果我在寻找@id='2',该怎么办?我希望在祖先之前支持当前节点的结果,但能够回退。
(/container/container/ancestor-or-self::container/data[@id="1"])[last()]
//container[last()]
(//container)[last()]