I am trying to find all the element names which follow the below two rules.
1. elements should have the <set>erase</set>
2. if two or more elements have the <set>erase</set> in hierarchy (Ex: <b> and <d> both have <set>erase</set>) then only the parent node name has to be printed(ie <b> in this case).
So the required result for below xml needs to be :
b , y , p
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a>
<b>
<set>erase</set>
<d>
<set>erase</set>
</d>
</b>
<c>
<x>
</x>
</c>
<e>
<y>
<set>erase</set>
<q>
</q>
</y>
<z>
<p>
<set>erase</set>
</p>
</z>
</e>
</a>
When I use the query = (//set[contains(.,'erase')])[1] I get only node b in result set.
When I use the query = //set[contains(.,'erase')] I get all nodesList b,d,y,p in result set.
Can anyone help me find the query to result in nodeList b , y and p.
Here is the java code snippet I used.
XPath xpath = factory.newXPath();
String query = "//set[contains(.,'erase')]";
XPathExpression expr=null;
try {
expr = xpath.compile(query);
} catch (XPathExpressionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object result = null;
try {
result = expr.evaluate(doc, XPathConstants.NODESET);
} catch (XPathExpressionException e) {
e.printStackTrace();
}
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
String x = "";
Node n = nodes.item(i).getParentNode();
x=n.getNodeName();
while(!n.getNodeName().equalsIgnoreCase(request.getClass().getSimpleName())){
if ((n = n.getParentNode())!=null){
x=n.getNodeName()+"."+x;
}
}
System.out.println("Path: "+x);
output:
a.b
a.b.d
a.e.y
a.e.z.p
Could anyone help me figure out the query which results in only a.b , a.e.y and a.e.z.p
Let me know if you need more details. or any other use-case.
One expression that selects exactly the wanted elements is:
XSLT – based verification:
This transformation, when applied on the provided by Sean B. Durkin XML document:
evaluates the XPath expression above and outputs the names of the selected elements — the wanted, correct result is produced:
Do note that the following two expressions are quite incorrect:
Or:
These two expressions suffer from more than one problem:
They are relative expressions and regardless with which initial context they are applied, they cannot select all wanted elements in an hierarchy with undefined depth and structure.
set[text()='erase']selects not only an element of the form:…
but also elements of the form:
.3. Similarly:
selects elements of the form: