0

I am trying to parse the below xml to fetch the ScId element values based on certain condition. This condition is mentioned in the xpath string and then select the ScId value in xpathNext string.

<?xml version="1.0" encoding="ISO-8859-1"?>
<SchoolData>
<School>
<ScId>SC101-91</ScId>
    <Location>
      <Branch>
        <BranchId>Br-111</BranchId>
        <Type>Residential</Type>
        <RealType>Residential</RealType>
      </Branch>
      <Branch>
        <BranchId>BR-222</BranchId>
        <Type>Daycare</Type>
        <RealType>Daycare</RealType>
      </Branch>
      <Branch>
        <BranchId>Br-333</BranchId>
        <Type>Unknown</Type>
        <RealType>Unknown</RealType>
      </Branch>
    </Location>
</School>

<School>
<ScId>RC101-92</ScId>
    <Location>
      <Branch>
        <BranchId>Br-111</BranchId>
        <Type>Residential</Type>
        <RealType>Residential</RealType>
      </Branch>
      <Branch>
        <BranchId>BR-222</BranchId>
        <Type>Daycare</Type>
        <RealType>Daycare</RealType>
      </Branch>
      <Branch>
        <BranchId>Br-333</BranchId>
        <Type>Unknown</Type>
        <RealType>Unknown</RealType>
      </Branch>
    </Location>
</School>
</SchoolData>

I'm using nested xpath query using VTD xml parser to fetch the ScId value which start with RC and Type = Daycare.

Below is the code

String xpath = "/*/School[starts-with(ScId,'RC')]/Location/Branch[Type='Daycare']";
        String xml = "/school.xml";
        
        final VTDGenHuge vg = new VTDGenHuge();
        System.out.println("Parsing");
        vg.parseFile(xml, true, VTDGenHuge.MEM_MAPPED);

        VTDNavHuge vn = vg.getNav();

        AutoPilotHuge aph = new AutoPilotHuge(vn);
        String xpathNext = "concat(//ScId,'-NEW')";
        aph.selectXPath(xpath);
        while ((aph.evalXPath()) != -1) {
            getparsedValue(vn,xpathNext);
            
        }

and parsing logic is

private static String getparsedValue(final VTDNavHuge vn, String xpath) throws NavException,

    XPathParseException, XPathEvalException, XPathParseExceptionHuge, XPathEvalExceptionHuge, NavExceptionHuge{

        String value = null;
        vn.push();
        
        AutoPilotHuge ap = new AutoPilotHuge(vn);
        ap.selectXPath(xpath);

        ap.bind(vn);
        value = ap.evalXPathToString();
        System.out.println("parsed value is " +value);
        vn.pop();
        return value;
    }

This returns me

parsed value is SC101-91-NEW

while I'm expecting it to be

parsed value is RC101-92-NEW

technocrat
  • 701
  • 5
  • 13
  • 23
  • 1
    You should realize that the XPath expression `//ScId` starts from the root of the document, again. So it selects the first matching `ScId` and **not** the one you selected with your previous expression. – zx485 Mar 21 '22 at 13:01
  • OK, so how do we select the ScId from the current node. concat(./ScId,'-NEW') this won't work either. – technocrat Mar 21 '22 at 13:10

1 Answers1

1

Maybe this XPath-1.0 expression helps you. I have no Java available to test it.

/*/School[starts-with(ScId,'RC') and Location/Branch[Type='Daycare']]

This iterates over all <School> elements that satisfy the conditions.
To get the <ScId>, add the string /ScId to the end of the expression.

zx485
  • 28,498
  • 28
  • 50
  • 59
  • That works perfectly. In the meanwhile, I was also able to get the current ScId using concat(../../ScId,'-NEW'). Although your answer is more sensible. Thanks – technocrat Mar 21 '22 at 15:30