Given the following XML file :
<a m="1">
<b n="1" o="2">
<c p="3">3</c>
<d/>
</b>
<b n="1" o="2">
<c p="3">3</c>
<d q="3">
<e r="2">2</e>
</d>
<f s="1"/>
</b>
</a>
How can I find the following expressions :
1. count(/*/*/*) = 5
2. count (/*//*) = 6
3. count (/*/*//@*) = 4
I ran the xml file with those xpath expressions in Java , but I don't understand why the answers are 5,6,4 .
Can someone please explain how can I calculate the above expressions (not using a java code) but by understanding the actual concept of the commands /*/*/*
and /*//*
and /*/*//@*
?
Much appreciated
/*/*/*
This selects all "grand-children of the top element -- these are: c
, d
, c
, d
/*//*
This selects all descendant elements of the top element: b
, c
, d
, b
, c
, d
, e
, f
/*/*//@*
This selects all attributes either of children of the top element or of their descendants: n
, o
, p
, n
, o
, p
, q
, r
, s
.
Therefore, the counts produced must be, respectively:
4, 8, 9
XSLT - based verification:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select="count(/*/*/*)"/>
=========
<xsl:value-of select="count(/*//*)"/>
=========
<xsl:value-of select="count(/*/*//@*)"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is performed on the provided XML document (never, never ever present the document with a picture!!!):
<a m="1">
<b n="1" o="2">
<c p="3">3</c>
<d/>
</b>
<b n="1" o="2">
<c p="3">3</c>
<d q="3">
<e r="2">2</e>
</d>
</b>
<f s="1"/>
</a>
The Xpath expressions are evaluated and their results are copied to the output:
4
=========
8
=========
9
1- Find direct descendant of elements which are direct descendant of direct descendants of root element
In this case
/a/b[1]/c
/a/b[1]/d
/a/b[2]/c
/a/b[2]/d
/a/b[2]/f
are your answer.
2- all descendant (direct or indirect) element under first level of elements
In this case
/a/b[1]/c
/a/b[1]/d
/a/b[2]/c
/a/b[2]/d
/a/b[2]/d/e
/a/b[2]/f
are your answer.
3- find all attributes which belong all descendants of direct descendants of first level elements
In this case
/b[1]/@n
/b[1]/@o
/b[1]/c/@p
/b[2]/@n
/b[2]/@o
/b[2]/c/@p
/b[2]/d/@q
/b[2]/d/e/@r
/b[2]/f/@s
are your answer.
As you can see here answer to 3rd case is 9, since you wrote it wrong. To make it return your must change it as count(/*/*/*/@*)
EDIT: corrected indices as noted by Mimo.
Run your java code again but without the count function. You'll get back a list of nodes (sometimes elements and sometime attributes). Iterate over the list and write out the name of each node. That will help you understand which of the nodes are included in each of the counts.