How to select a node using XPath if sibling node has a specific value?

XmlXpath

Xml Problem Overview


I have the following document:

<a>
  <bb>abc</bb>
  <cc>ccc</cc>
  <dd>ddd</dd>
</a>
<a>
  <bb>zz</bb>
  <cc>1</cc>
  <dd>2</dd>
</a>

How can I get the value of <cc> using XPath if <bb> is zz?

Xml Solutions


Solution 1 - Xml

Not sure why everybody is querying for siblings, you can also check for <bb/>-elements matching the predicate from <a/>'s predicate:

//a[bb/text() = "zz"]/cc/text()

Solution 2 - Xml

What you need is following-sibling XPath axis

//a/bb[text()="zz"]/following-sibling::cc[1]/text()

Test the Xpath here: http://www.xpathtester.com/obj/b55ec3ac-dfa4-4f44-81e8-f963ea4a0625

Solution 3 - Xml

Q: How to select a node using XPath if sibling node has a specific value?
Because there are only "XPath Axes" for following-siblings and preceding-siblings, you can use one of them if the position is fixed.

But better: Look for cc were the parent has child bb with value 'zz':

//cc[../bb='zz']

Solution 4 - Xml

First off, your example is not well-formed XML. Overlooking that and that you didn't describe your intents very well (What exactly do you want to select on which condition?), I assume you want to do this:

//cc[preceding-sibling::bb[text()="zz"]]/text()

It selects

TEXT VALUES OF ALL <CC> ELEMENTS
//cc                                    /text()
    THAT HAVE A PRECEDING SIBLING <BB>
    [preceding-sibling::bb             ]
                          THAT HAS TEXT VALUE EQUAL TO "zz"
                          [text()="zz"]

You could write is also as

//bb[text()="zz"]/following-sibling::cc/text()

Please look at the spec, it has some very well readable examples from which you'll learn a lot.

Solution 5 - Xml

Another solution for this problem is

//bb[contains(.,'zz')]/../cc/text()

Explanation: Any bb that contains 'zz' string in all the child nodes of bb then going to parent node of that bb using .., now that we can access the cc so returning text.

I hope that explanation isn't complex.

Solution 6 - Xml

//a/cc[../bb='zz']/text()

//a : Selects all 'a' elements no matter where it is.

//a/cc : Selects 'cc' elements that are children of the 'a' element (no matter where a is).

.. : Selects the parent of the current node.

[../bb='zz'] : where value of sibling 'bb' element is zz.

Reference: http://www.w3schools.com/xsl/xpath_syntax.asp

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHOE SENGKIANGView Question on Stackoverflow
Solution 1 - XmlJens EratView Answer on Stackoverflow
Solution 2 - XmlStanleyView Answer on Stackoverflow
Solution 3 - Xmlhr_117View Answer on Stackoverflow
Solution 4 - XmlPetr JanečekView Answer on Stackoverflow
Solution 5 - XmlSaleh MahmoodView Answer on Stackoverflow
Solution 6 - XmlBae Cheol ShinView Answer on Stackoverflow