César
César

Reputation: 162

Java How to extract a complete XML block with xpath

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

Answers (4)

vtd-xml-author
vtd-xml-author

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

azro
azro

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

Usman Mohyuddin
Usman Mohyuddin

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.

Demo of the Query

I hope this will work for you.

Upvotes: 0

kumesana
kumesana

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

Related Questions