Reputation: 162
I have XML files like this:
<A>
<B>
<C>
<id>0</id>
</C>
</B>
<B>
<C>
<id>1</id>
</C>
</B>
</A>
And I would like to get B block when C has a specific id. For example, if I want to get the block with id=1, I want this reponse:
<B>
<C>
<id>1</id>
</C>
</B>
But I do not know how can I get the part I want. I tried:
Node result = (Node)xPath.evaluate("A/B/C[id = '1']", doc, XPathConstants.NODE);
But returns an C block, when I want B block.
And:
Node result = (Node)xPath.evaluate("B[A/B/C[id = '1']]", doc, XPathConstants.NODE);
returns null.
Also I have read the official documentation but I did not find anything:
https://msdn.microsoft.com/en-us/library/ms256471(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/ms256086(v=vs.110).aspx
Thanks.
Upvotes: 1
Views: 1073
Reputation: 3377
This is the code to extract a block of text with vtd-xml.. and XPath. The key is using getElementFragment, which returns the offset and length of a fragment in the source XML document.
public static void main(String[] args) throws VTDException{
String xml="<A>"+
"<B>\n"+
"<C>\n"+
"<id>0</id>\n"+
"</C>\n"+
"</B>\n"+
"<B>\n"+
"<C>\n"+
"<id>1</id>\n"+
"</C>\n"+
"</B>\n"+
"</A>\n";
VTDGen vg = new VTDGen();
vg.setDoc(xml.getBytes());
vg.parse(false);
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/A/B[C/id='1']");
System.out.println("====>"+ap.getExprString());
int i=0,count=0;
System.out.println(" token count ====> "+ vn.getTokenCount() );
while((i=ap.evalXPath())!=-1){
long l = vn.getElementFragment();
System.out.println("fragment content ====>"+
new String(vn.getXML().getBytes(),(int)l,(int)(l>>32)));
}
System.out.println(" count ===> "+count);
}
Upvotes: 0
Reputation: 54148
Node result = ((Node)xPath.evaluate("A/B/C[id = '1']", doc, XPathConstants.NODE))
.getParent();
This is the solution with the Java method, get a C element, and then take its parent
Upvotes: 0
Reputation: 32
You can achieve this by using parent axes in xpath query. As you mentioned, you want to get B block when C has a specific id. You have to query with parent axes just like
//*[id="1"]/parent::B
Here is detail s of the command.
//* is the nested-path till xpath finds id.
[id="1"] is condition according to you requirement.
/parent::B will return parents node from id tag to B tag including B.
I hope this will work for you.
Upvotes: 0
Reputation: 2490
Predicates simply mean "only keep this element if it respects the condition I put in this predicate"
So simply,
A/B[C/id = 1]
Upvotes: 1