DevOps85
DevOps85

Reputation: 6523

Parsing XML with filter

i parse XML document in java with:

doc = DocumentBuilderFactory
           .newInstance()
           .newDocumentBuilder()
           .parse(new URL(url).openStream());

work, but is possible to parse with some filter? for example my XML file have one attribute priority, is possible to parse with filter for example priority>8 ?

So in the doc have only element with priority > 8.

Example xml:

<url>
<loc>http</loc>
<lastmod>2015-02-26</lastmod>
<title>Hello</titolo>
<priority>1.0</priority>
</url>
...

Thanks

Upvotes: 1

Views: 2642

Answers (2)

Ravi K Thapliyal
Ravi K Thapliyal

Reputation: 51711

For the following sample input file named urls.xml

<root>
    <url>
        <loc>http</loc>
        <lastmod>2015-02-26</lastmod>
        <title>Hello</title>
        <priority>1.0</priority>
    </url>
    <url>
        <loc>http</loc>
        <lastmod>2015-02-26</lastmod>
        <title>Hello</title>
        <priority>7.0</priority>
    </url>
    <url>
        <loc>http</loc>
        <lastmod>2015-02-26</lastmod>
        <title>Hello</title>
        <priority>10.0</priority>
    </url>
</root>

You first create the full Document tree as usual

Document document = DocumentBuilderFactory
           .newInstance()
           .newDocumentBuilder()
           .parse(new File("urls.xml"));

Then run the XPath query that selects all the Nodes above a certain priority

XPathExpression expr = XPathFactory.newInstance()
                      .newXPath().compile("//url[priority > 5]");
NodeList urls = (NodeList) expr.evaluate(document, XPathConstants.NODESET);

If you want to serialize the results to another xml file, create a new Document first.

Document result = DocumentBuilderFactory.newInstance()
        .newDocumentBuilder().newDocument();
Node root = result.createElement("results");
result.appendChild(root);

Then append the filtered url Nodes as

for (int i = 0; i < urls.getLength(); i++) {
    Node copy = result.importNode(urls.item(i), true);
    root.appendChild(result.createTextNode("\n\t"));
    root.appendChild(copy);
}
root.appendChild(result.createTextNode("\n"));

Now, all you need to do is to serialize the new Document to a String and write that out to a file. Here's I'm just printing it out on to the console.

System.out.println(
        ((DOMImplementationLS) result.getImplementation())
        .createLSSerializer().writeToString(result));

Output:

<?xml version="1.0" encoding="UTF-16"?>
<results>
    <url>
        <loc>http</loc>
        <lastmod>2015-02-26</lastmod>
        <title>Hello</title>
        <priority>7.0</priority>
    </url>
    <url>
        <loc>http</loc>
        <lastmod>2015-02-26</lastmod>
        <title>Hello</title>
        <priority>10.0</priority>
    </url>
</results>

Upvotes: 1

Jeff Watkins
Jeff Watkins

Reputation: 6359

You should use XPath to find the elements you require:

XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile([your xpath here]);

Then...

NodeList nl = (NodeList) expr.evaluate(doc);

... to get the nodes you require. You can use...

for(Node node in nl) {
    if (node.getNodeType() == Node.ELEMENT_NODE) {
    }
}

... to pull out only the genuine elements.

Of course, you'll need to also build up a basic XPath expression to find the nodes you require.

Upvotes: 1

Related Questions