Xpath to select only direct siblings with appropriate attributes
I have the following sample document:
<root> <p class="b">A</p> <p class="b">B</p> <p class="a">C</p> <p class="a">D</p> <p class="b">E</p> <x> <p class="b">F</p> </x> </root> I am looking for an xpath expression that selects all direct siblings from a given node with the corresponding class attributes, and not with a brother. In the above example, the first two <p class="b"> AB should be selected; similar to the two <p class="a"> CDs, as well as the fifth single <p class="b"> E, since it has no direct siblings; similar to a single <p class="b"> F inside <x> . Note that in this context, B and C are not direct siblings, because they have a different class attribute!
What I have:
xml.xpath("//p") # This selects all six <p> elements. xml.xpath("//p[@class='b']") # This selects all four <p class="b"> elements. xml.xpath("//p/following-sibling::p[@class='b']") # This selects all <p class="b"> sibling elements, even though not direct siblings. In the last expression, the fifth brother is also chosen, although there are inappropriate brothers and sisters between them.
How to select only direct siblings with the same class value?
Change To clarify: note how the last two are separate, not siblings!
Change I saved an example here . An Xpath expression based on /root/p[1] should select A, B, C, D
To get your next brother, you can add position - 1, which means nearby.
following-sibling::*[1] To make sure that the next sibling has a specific node type, you can add the following filter, where p is the node type we want to map.
[self::p] If you need only those that have the same attribute, you will also need to specify an attribute for the first p element.
So, if you just need elements of the bp class that are immediately after the element of the bp class, you can do the following. This will just give you the second element of p.
//p[@class='b']/following-sibling::*[1][@class='b'][self:p] It sounds like you really need any element of class b that is next to another element of class b. In this case, you can check the next and previous brothers. The following will provide you with the first 2 p elements.
//p[@class='b'][following-sibling::*[1][@class='b'][self::p] or preceding-sibling::*[1][@class='b'][self::p]] How about something like this:
//p[@class='b']/following-sibling::p[following-sibling::p[@class='a'] and @class='b'] It returns all of the following siblings that are @class='b' , and they have the following siblings with @class='a' . Although this would not work for the last <p> , since he does not have the following siblings.