user2142786
user2142786

Reputation: 1482

How to Read all nodes of xml using xpathh in java?

I have an xml file and i want to read value of all the child nodes of xml . my xml is

 <branches>
        <branch-area name="abc">
            <branch>
                <branch-name> xyz Street</branch-name>
                <branchID>5689742</branchID>
                <branchAddress>xyz address</branchAddress> 
                <atm>true</atm>
                <branch>true</branch>
                <tab title="Contact">
      <![CDATA[<table>
        <tr>
            <td class="head">Branch</td>
            <td>bandra Street</td>
        </tr>
        <tr>
            <td class="head">Address</td>
            <td>bandra Street</td>
        </tr>
        <tr>
            <td class="head">Sort Code</td>
            <td>215863</td>
        </tr>
        </table>]]>
    </tab>
            </branch>
        </branch-area>
        <branch-area name="def 11">
            <branch>
                <branch-name>pqr</branch-name>
                <branchID>123456</branchID>
                 <branchAddress>pqr address </branchAddress>
                 <atm>true</atm>
                 <branch>true</branch>
                 <tab title="Contact">
      <![CDATA[<table>
        <tr>
            <td class="head">Branch</td>
            <td>bandra Street</td>
        </tr>
        <tr>
            <td class="head">Address</td>
            <td>bandra Street</td>
        </tr>
        <tr>
            <td class="head">Sort Code</td>
            <td>215863</td>
        </tr>
        </table>]]>
           </tab>
            </branch>
        </branch-area>
        <branch-area name="ghi 14">
            <branch>
                <branch-name>jkl</branch-name>
                <branchID>589674</branchID>
                <branchAddress>jkl address</branchAddress>
                <atm>true</atm>
                <branch>true</branch>
<tab title="Contact">
      <![CDATA[<table>
        <tr>
            <td class="head">Branch</td>
            <td>bandra Street</td>
        </tr>
        <tr>
            <td class="head">Address</td>
            <td>bandra Street</td>
        </tr>
        <tr>
            <td class="head">Sort Code</td>
            <td>215863</td>
        </tr>
        </table>]]>
    </tab>
            </branch>
        </branch-area>
    </branches>

and i am using this xpath expreesion for getting the particular branch.

String  xpathExpression = "/branches/branch-area[name='abc']/branch";

it is returning me the particular branch i.e

    <branch>
                    <branch-name> xyz Street</branch-name>
                    <branchID>5689742</branchID>
                    <branchAddress>xyz address</branchAddress> 
                    <atm>true</atm>
                    <branch>true</branch>
<tab title="Contact">
      <![CDATA[<table>
        <tr>
            <td class="head">Branch</td>
            <td>bandra Street</td>
        </tr>
        <tr>
            <td class="head">Address</td>
            <td>bandra Street</td>
        </tr>
        <tr>
            <td class="head">Sort Code</td>
            <td>215863</td>
        </tr>
        </table>]]>
    </tab>
                </branch>

but i want to get the value of its child like branch-name branchID etc for that does i need to use another xpath expression for each child node or there is another way also ? if yes please guide me

Upvotes: 0

Views: 124

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347334

You could...

Use a path like /branches/branch-area[@name='abc']/branch/* which will return you a NodeList of all the child nodes contained with branch.

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression branchExp = xpath.compile("/branches/branch-area[@name='abc']/branch/*");
NodeList branchNodes = (NodeList) branchExp.evaluate(dom, XPathConstants.NODESET);
System.out.println(branchNodes.getLength());
for (int index = 0; index < branchNodes.getLength(); index++) {
    Node node = branchNodes.item(index);
    System.out.println(node.getTextContent());
}

Which outputs something like...

5
 xyz Street
5689742
xyz address
true

You could...

Search for each individual sub node, using the branch node as the parent node for the search...

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression branchExp = xpath.compile("/branches/branch-area[@name='abc']/branch");
Node branchNode = (Node) branchExp.evaluate(dom, XPathConstants.NODE);

XPathExpression nameExp = xpath.compile("branch-name/text()");
String name = (String) nameExp.evaluate(branchNode, XPathConstants.STRING);
System.out.println("Name = " + name);

Which outputs something like...

Name =  xyz Street

Updated...

So, CDATA isn't processed by xPath, instead, you need to get the text of the tab node, parse it into a Document and the run xPath over it, for example...

try {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document dom = db.parse(new File("Test.xml"));
    XPath xpath = XPathFactory.newInstance().newXPath();

    // Find the "thing" node...
    XPathExpression thingExpr = xpath.compile("/branches/branch-area/branch/tab");
    Node things = (Node) thingExpr.evaluate(dom, XPathConstants.NODE);
    String table = things.getTextContent();

    ByteArrayInputStream bais = new ByteArrayInputStream(table.getBytes());
    Document tblDom = db.parse(bais);
    XPathExpression tableExp = xpath.compile("/table/tr[td[text()='Sort Code']]/td[not(@*)]");
    NodeList nodes = (NodeList) tableExp.evaluate(tblDom, XPathConstants.NODESET);
    System.out.println(nodes.getLength());
    for (int index = 0; index < nodes.getLength(); index++) {
        Node node = nodes.item(index);
        System.out.println(node.getTextContent());
    }
} catch (Exception exp) {
    exp.printStackTrace();
}

Upvotes: 1

Related Questions