代码之家  ›  专栏  ›  技术社区  ›  Nick Spacek

在xpath中选择第一个结果

  •  9
  • Nick Spacek  · 技术社区  · 16 年前

    我看过这个问题: Select first instance only with 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>
    

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

    编辑: 我想要的是一个ID为1的“数据”节点,它应该首先来自最低的节点或最近的祖先。所以,如果我在“current”(/container/container)上找不到它,我应该看看祖先,找到最近的祖先(或者最后找不到任何东西)。我尝试过:

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

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

    5 回复  |  直到 11 年前
        1
  •  6
  •   Daniel Martin    16 年前

    你是如何尝试在最后一个()上附加的?我认为这应该有效:

    /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>
    

    但是,根据StackOverflow的精神,我可以将我的答案与其他答案中的一个结合起来,得到在所有情况下都有效的答案:

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

    顺便说一句,如果一个容器有多个@id-is-1<data>子容器,这将返回所有子容器。只返回第一个这样的<data>元素:

    (/container/container/ancestor-or-self::container[data[@id="1"]])[last()]/data[@id="1"][1]
    
        2
  •  11
  •   David Webb    16 年前

    确定 last() 范围正确。尝试:

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

    类似地:

    //container[last()]
    

    还有:

    (//container)[last()]
    

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

        3
  •  1
  •   annakata    16 年前

    我对你的要求不是百分之百的清楚,但如果我读得对,也许你只是想:

    /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处返回最低的顺序-这就是您想要的顺序-但是您需要在其上放置第二个条件,该节点也有一个您感兴趣的数据节点,一旦满足这些条件,您就拥有了正确的节点,现在您只想进一步挖掘到实际的数据。a.

    99%的时间xpath会变得更容易,如果你把它拆开并把它当作一个算法的话:)

        4
  •  0
  •   skaffman    16 年前

    而不是

    @id="1"
    

    你试过了吗?

    position() == 1
    
        5
  •  0
  •   user3121414    11 年前

    尝试 [位置()= 1

    前任。

    /容器/容器/祖先或self::container/data[position()=1]