Xpath Expression to get immediate and non-leaf children - xpath

i'd like to have an xpath expression to get only all immediate and non-leaf children of a node.
When i run the expression for such an XML tree:
<root>
<attribute1>a</attribute1>
<attribute2>b</attribute2>
<attribute3>c</attribute3>
<ElementA>
<ElementB>
<ElementC>AC</ElementC>
</ElementB>
</ElementA>
<ElementX>
<ElementB1>
<ElementC1>C1</ElementC1>
</ElementB1>
</ElementX>
<Other>
<ElementB2>B2</ElementB2>
</Other>
<NewOne>
<ElementB3>
<ElementC3>
<ElementC4>C4</ElementC4>
</ElementC3>
</ElementB3>
</NewOne>
</root>
I should get ElementA, ElementX, Other, NewOne.
Thans for any help.

This would be:
/root/*[*]
(the predicate is there to make sure that selected nodes have at least one child)

Related

XPath difference between two similar path and other questions

I've to made some exercices but
I don't really understand the difference between two similar path
I've the tree :
<b>
<t></t>
<a>
<n></n>
<p></p>
<p></p>
</a>
<a>
<n></n>
<p></p>
</a>
<a></a>
</b>
And we expect that each final tag contain one text node.
I've to explain the difference between //a//text() and //a/text()
I see that //a//text() return all text nodes and it seems legit,
but why //a/text() return the last "a node" -> text node ?
Another question :
why //p[1] return for each "a node", the first "p" child node ?
-> I've two results
<b>
<t></t>
<a>
<n></n>
**<p></p>**
<p></p>
</a>
<a>
<n></n>
**<p></p>**
</a>
<a></a>
</b>
Why the answer is not the first "p" node for the whole document ?
Thanks for all !
Difference between 1: //a//text() and 2: //a/text()
Let's break it down: //a selects all a elements, no matter where they are in the document. Suppose you have /a, that would select all root a elements.
If the / path expression comes after another element in an XPath expression, it will select elements directly descending the element before that in the XPath expression (ie child elements).
If the // path expression comes after another element in an XPath expression, it will select all elements that are descendant of the previous element, no matter where they are under the previous element.
Applying to your two XPath expressions:
//a//text(): Select all a elements no matter where they are in the document, and for those elements select text() no matter where they are under the a elements selected.
//a/text(): Select all a elements no matter where they are in the document, and for those elements select any direct descendant text().
Why //p[1] returns for each "a node", the first "p" child node?
Suppose you were to write //a/p[1], this would select the first p child element of any a element anywhere in the document. By writing //p[1] you are omitting an explicit parent element, but the predicate still selects the first child element of any parent the p element has.
In this case there are two parent a elements, for which the first p child element is selected.
It would be good to search for a good introduction to XPath on your favorite search engine. I've always found this one from w3schools.com to be a good one.

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.

Use xpath to locate a complex element with attributes and children

Given this XML
<well bulkShift="0.000000" diameter="5.000000" hidden="false" name="67-1-TpX-10" filename="67-1-TpX-10.well">
<metadata/>
<unit>ftUS</unit>
<colour blue="1.000000" green="1.000000" hue="" red="1.000000"/>
<tvd clip="false"/>
<associatedcheckshot>25-1-X-14</associatedcheckshot>
<associatedwelllog>HDRA_67-1-TpX-10</associatedwelllog>
<associatedwelllog>NPHI_67-1-TpX-10</associatedwelllog>
</well>
I can select the element with this XPath
//well[#bulkShift=0 and #diameter=5 and #hidden='false' and #name='67-1-TpX-10' and #filename='67-1-TpX-10.well']
However I need to be much more specific in that I need to find the element with these specific child nodes given that the child elements (metadata,unit,colour, etc) can appear in any order inside the element.
Ideally I'd like to be able to select this node with only a single XPath query.
Can anyone help?
This template match also childs and attributed on childs
<xsl:template match="well[#hidden='false'][./unit='ftUS' or ./tvd/#clip='false']">
well found!
</xsl:template>
or in one go:
<xsl:template match="well[#hidden='false' and (./unit='ftUS' or ./tvd/#clip='false')]">
well found!
</xsl:template>
You can add the test for children like the test for attributes to your predicate
e.g.:
//well[#bulkShift=0 and #diameter=5 and #hidden='false' and #name='67-1-TpX-10' and #filename='67-1-TpX-10.well']
[metadata and unit and colour]
Having a list off predicates [ predicate1 ][ predicate2 ] is the same as have one with and operation.

Xpath test for ancestor attribute not equal string

I'm trying to test if an attribute on an ancestor of an element not equal a string.
Here is my XML...
<aaa att="xyz">
<bbb>
<ccc/>
</bbb>
</aaa>
<aaa att="mno">
<bbb>
<ccc/>
</bbb>
</aaa>
If I'm acting on element ccc, I'm trying to test that its grandparent aaa #att doesn't equal "xyz".
I currently have this...
ancestor::aaa[not(contains(#att, 'xyz'))]
Thanks!
Assuming that by saying an ancestor of an element you're referring to an element with child elements, this XPath expression should do:
//*[*/ccc][#att != 'xyz']
It selects
all nodes
that have at least one <ccc> grandchild node
and that have an att attribute whose value is not xyz.
Update: Restricted test to grandparents of <ccc>.
Update 2: Adapted to your revised question:
//ccc[../parent::aaa/#att != 'xyz']
Selects
all <ccc> elements
that have a grandparent <aaa> with its attribute att set to a value that is not xyz

Find sibling node after specified node is found

Consider the following very simplified example.
<n></n>
<k></k>
<m></m>
<k></k>
How can I search for a first k sibling after m node? Basically, find some node and then continue searching from that node.
How can I search for a first k sibling after m node? Basically, find
some node and then continue searching from that node.
Assuming that we have the following well-formed XML document:
<t>
<n></n>
<k></k>
<m></m>
<k></k>
</t>
then the following XPath expression:
/*/m[1]/following-sibling::k[1]
selects the first k following-sibling of the first m child of the top element of the XML document.
nice question : try it ........
<a>
<n></n>
<k></k>
<m></m>
<k></k> <====
<k></k>
<m></m>
<k></k>
</a>
/a/k[. = preceding::m][1]

Resources