XPath - select nodes without certain internal nodes - xpath

<node1>
<node2>
<node4>
<node3>
</node3>
</node4>
</node2>
<node2>
</node2>
</node1>
How do I select all node2 which doesn't have internal node3? The result should be the second node2.
PS: node3 could be in any level, but must be in node2

x-path:
//node2[not(.//node3)]
will select all node2s in the whole document with no descendant node3.

Related

Xpath Find Last Non-None Element

I have an Xml which goes like
<Node1>
<Node2 name = "A" >
<Node3>
<ChildNode>blah blah</ChildNode>
</Node3>
</Node2>
<Node2 name = "B" >
<Node3>
<ChildNode></ChildNode>
</Node3>
</Node2>
</Node1>
My requirement is to find the last node which is "Not None" here..
I tried '/Node1/Node2[ last() ]//Node3ChildNode/text( )' but here the last node is empty so want to default to the previous node.
What would be the best way to do that via Xpath ?
Select the last Node 3 with not empty ChildNode
(/Node1/Node2[Node3/ChildNode/text()])[last()]/Node3/ChildNode/text()
Or select the last one from all not empty ChildNode
(/Node1/Node2/Node3/ChildNode/text())[last()]

Xpath to select only nodes where child has certain value

Hope someone can help
<root>
<a>
<b>1.00</b>
<c>
<d/>
</c>
</a>
<a>
<b/>
</a>
</root>
How can I formulate an XPATH expression in which I get b's value only if the parent node has a D node
i.e., in the previous example I would get only the value of the first b, as the second a node doesn't have a /c/d
Try //*[.//d]/b
i.e. any b node, child of any node -- * -- that has a d descendant
You need to use a predicate to filter
/root/a[c/d]/b
i.e. starting with the root element, find all its a children that have a c/d, and finally extract the b children of these filtered a elements.

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

NOKOGIRI::XML | Delete parent where child count = 0

All I want to do is parse the XML below and delete Peter and Sam element as they dont have any children (also can say empty) and President element after that as it will be empty.
This nested thing is driving me crazy!
<Office id="xyz" scope="node">
<John>
<age>23</age>
<ssn>230231111</ssn>
</John>
<Peter>
</Peter>
<John>
<age>25</age>
<ssn>222222222</ssn>
</John>
<President>
<Sam>
</Sam>
</President>
</Office>
It looks like you want:
doc.xpath('//*[not(*) and normalize-space(text())=""]').remove
not(*) selects nodes without children
normalize-space(text())="" selects nodes with empty text (trimmed
whitespace)
Do it 2x to remove President too.

How to get content from next node

I have an XML below -
<document>
<node name="Node 0 Text here" ID="01" >aa
</node>
<node name="Node 1 Text here" ID="11">bb
</node>
<node name="Node 2 Text here" ID="12">cc
</node>
<node name="Node 3 Text here" ID="22">dd
</node>
<node name="Node 4 Text here" ID="23">ee
</node>
</document>
I need to search content in a particular node within this XML.
If search keyword does not exist in that node, then I have to begin searching from the next node of current node, you could say sibling.
If that keyword does not exist in all the nodes after the current node then it should begin search from start..
I have to achieve this in my code behind- dotnet class. I have used -
XmlNodeList xmlNodes = xd.SelectNodes("//12/following-sibling::*");
Here, 12 refers to nodeid of the current node,which will be passed as an argument. But I am getting error.
Any help is appreciated.
I need to search content in a particular node within this XML
to get a node matching by its content, the XPath is:
node[contains(text(),'aa')]
This will return the first node for example and any other node whose content text contains aa.
If search keyword does not exist in that node, then I have to begin searching from the next node of current node, you could say sibling. If that keyword does not exist in all the nodes after the current node then it should begin search from start.
This sentence does not make much sense to XPath. The expression above will return all nodes matching the keyword. If you want the first matched node you can get it from the XmlNodeList after or directly from the XPath expression changing it to:
node[contains(text(),'aa')][1]
12 refers to nodeid of the current node,which will be passed as an argument
That's not correct. To select the node by id you should use, for instance:
node[#id=12]/text()
This will get the content of the node with id=12.
Use:
(/*/node[ID='12']/following-sibling::*[contains(.,$pattern)][1]
|
/*/node[ID='12']/preceding-sibling::*[contains(.,$pattern)][1]
)
[last()]
This expression selects the last from the two wanted selections -- the first of the following siblings that contains the value of $pattern and the first of the preceding siblings that contains the value of $pattern.
You need to substitute $pattern with the exact value you want to serch for.

Resources