Xpath sub selector - xpath

I want to select a node that has a sub node with particular text() = '...'. Any idea how to write this xpath expression?
//Node[?]

If the "sub node" is a child element named subnode, then use:
//Node[subnode='...']
Or, if it could be a child element having any name, use:
//Node[*='...']
If the "sub node" could be nested at an arbitrary depth, then use:
//Node[descendant::*='...']

Something like:
//yournode[subnode/text() = 'whatever']
?

Related

XPath with specific following sibling case

I have structure that looks something like this
<p>
<br>
<b>Text to fetch </b>
<br>
"Some random text"
<b>Text not to fetch</b>
I need XPath that will allow me to fetch following sibling of the br element only if there is no text between br element and his following sibling.
If I do something like this
//br/following-sibling::b/text()[1]
It will fetch both Text to fetch and Text not to fetch, while I only need Text to fetch.
Another possible XPath :
//br/following-sibling::node()[normalize-space()][1][self::b]/text()
brief explanation:
//br/following-sibling::node(): find all nodes that is following-sibling of br element, where the nodes are..
[normalize-space()]: not empty (whitespace only), then..
[1]: for each br found, take only the first of such node, then..
[self::b]: check if the node is a b element, then if it is a b element..
/text(): return text node that is child of the b element
Try below XPath to avoid matching b nodes with preceding sibling text:
//br/following-sibling::b[not(preceding-sibling::text()[1][normalize-space()])]/text()

XPath with two conditions

I want to select the div with class "bmBidderButtonText" and with "Low" as inner text, what should I do?
<div class="bmBidderButtonText"><div class="bmBidderButtonArrow"></div>Low</div>
<div class="bmBidderButtonText"><div class="bmBidderButtonArrow"></div>High</div>
Merely //div[#class="bmBidderButtonText"] will select two divs, but how should I include the "Low" as inner text as condition within the xpath?
You can use . to reference current context element, so implementing additional criteria of "...and with 'Low' as inner text" in XPath would be as simple as adding and .='Low' in the predicate of your initial XPath :
//div[#class="bmBidderButtonText" and .="Low"]
demo
Try this below xpath
//div[#class='bmBidderButtonText'][text() ='Low']
Explanation:- Use class attribute of <div> tag along with the text method.
use and:
//div[#class="bmBidderButtonText" and contains(., "Low")]
You can use contains() for this reason:
//div[contains(text(), 'Low')]
Additional resources:
Choosing Effective XPaths

XPath Wildcard -- Any Node Name, Must have Specific Attribute Value

I am having difficulty figuring out an XPath query that would allow me to return nodes based on the value of the Program attribute in the example below. For example, I would like to be able to search all nodes for a value of the Program attribute = "011.pas". I tried /Items/*[Program="012.pas"] and also /Items/Item*[Program="01.pas"] but neither works. What is the correct expression?
<Items>
<Item0 Program="01.pas"></Item0>
<Item1 Program="011.pas"></Item1>
</Items>
The attribute is selected with #Program, the child elements of the Items element with /Items/*, so you want /Items/*[#Program = '011.pas'].
Try this :
/items/*[#Program='011.pas']

xpath get child node excluding parent

I'm looking for an xpath that will give me a child node only if the parent node doesn't equal a specific value. For example if I have an xml like the following:
<Grandpa><Dad><Son /></Dad><Son /></Grandpa>
I want to return the Son element outside the Dad element.
This Xpath selects those Son elements whose parent element is not named Dad:
//Son[local-name(..) != 'Dad']
So, applied to this XML:
<Grandpa><Dad><Son a="1"/></Dad><Son a="2"/></Grandpa>
It will select:
<Son a="2"/>

XPATH filter tag-less children

Is there any way to specify that I want to select only tag-less child elements (in the following example - "text")?
<div>
<p>...</p>
"text"
</div>
The text() function matches text nodes. Example: //div/text() — matches all text children within all div elements.
Use:
/*/text()[normalize-space()]
This selects all text nodes that are children of the top element of the document and that do not consist only of white-space characters.
In the concrete example this will select only the text node with string value:
'
"text"
'
The XPath expressions:
/*/text()
or
/div/text()
both select two text nodes, the first of which contains only white-space and the second is the same text node as above:
'
"text"
'
select only tag-less child elements
To me this sounds like selecting all elements that don't have other elements as children. But then again, "text" in your example is not an element, but a text node, so I'm not really sure what do you want to select...
Anyway, here is a solution for selecting such elements.
//*[not(*)]
Selects all elements that don't have an element as a child. Replace the first * with an element name if you only want to select certain elements that don't have child elements. Also note that using // is generally slow since it runs through the whole document. Consider using more specific path when possible (like /div/*[not(*)] in this case).

Resources