用于选择兄弟姐妹的XPath

时间:2012-09-08 21:07:48

标签: .net xml xpath

我有以下xml:

<root>
    <a>value1</a>
    <b>value2</b>
    <c>value3</c>
    <a>value5</a>
    <d>value4</d>
    <b>value2</b>
    <b>value3</b>
    <a>value7</a>
</root>

我想在节点a之后选择第一个兄弟//b[text()='value2']如果它没有跟随另一个b节点(在这种情况下它将是<a>value5</a><a>value7</a>不应该被选中)。

这样做的xpath是什么?

我正在使用.net 4和xpath 1.0

更新

这是我从这里来的地方:我正在解析的文档有一个非常愚蠢的结构,可以用

来描述
<root>
    <key>key-value</key>
    <some-other-nodes>some other values</some-other-nodes>
    <key>an other key value</key>
    <value>the value</value>
</root>

我所描述的文档包含以下键值对: 密钥值 - &GT; {NULL} 另一个关键值 - &gt; {值}

如果重复关键节点,则重置key值。我需要一个xpath来选择特定键的值。因为在上面的示例中,//b[text()='value2']的第二个匹配后跟<b>value3</b>,所以密钥会重置为value3

2 个答案:

答案 0 :(得分:3)

使用

   //b[text()='value2']
          /following-sibling::b[last()]
                 /following-sibling::a[1]
  |
   //b[text()='value2']
        [not(following-sibling::b)]
             /following-sibling::a[1]

选择:

  1. 初始a元素的最后b个兄弟姐妹之后的第一个兄弟b,或者:

  2. 初始b元素的第一个以下兄弟,如果它没有任何其他兄弟姐妹b

  3. 这可以简化为

      //b[text()='value2']/../b[last()]/following-sibling::a[1]
    

    <强>更新

    //b[text()='value2']从提供的XML文档中选择 two` 元素时,OP还必须指定他希望在XPath表达式的第一个位置步骤中选择这两个中的哪一个。

    这是一个更精确的XPath表达式,其中$k是所选元素b[. = 'value2']的数字(1或2):

      (//b[text()='value2'])[$k]/../b[last()]/following-sibling::a[1]
    

    基于XSLT的验证

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:param name="k" select="1"/>
    
     <xsl:template match="/">
      <xsl:copy-of select=
      "(//b[text()='value2'])[$k]
          /../b[last()]
             /following-sibling::a[1]"/>
     </xsl:template>
    </xsl:stylesheet>
    

    在提供的XML文档上应用此转换时:

    <root>
        <a>value1</a>
        <b>value2</b>
        <c>value3</c>
        <a>value5</a>
        <d>value4</d>
        <b>value2</b>
        <b>value3</b>
        <a>value7</a>
    </root>
    

    评估XPath表达式并将此评估选择的元素复制到输出

    <a>value7</a>
    

答案 1 :(得分:2)

这是一个应该有效的方法:

//b[.='value2']/following-sibling::a[preceding-sibling::b[1][.='value2']]

简单地说,它选择a元素后面的b元素,其值为'value2',其中最新的b元素的值为'value2'

编辑:现在我考虑一下,我甚至不确定你是否需要第一部分。试试这个:

//a[preceding-sibling::b[1][.='value2']]