Armer B.
Armer B.

Reputation: 772

How to parse XML file with JxPath and DOM parser

I need simple example how can be possible to parse XML files with Java DOM parser and Apache JxPath. I am aware with DOM parser technology, but now I'm trying to integrate JxPath in my source.

I have searched in a network, but I can't find working example.

For test I've got this xml:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <cd gender="male">
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
  <cd gender="male">
    <title>Hide your heart</title>
    <artist>Bonnie Tyler</artist>
    <country>UK</country>
    <company>CBS Records</company>
    <price>9.90</price>
    <year>1988</year>
  </cd>
</catalog>

Java code:

File file = new File("Files/catalog.xml");
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
try
{
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    Document doc = docBuilder.parse(file);

    NodeList nList = doc.getElementsByTagName("cd");
    for(int j = 0; j<nList.getLength(); j++){

        Element element = (Element)nList.item(j);
        System.out.println(element.getElementsByTagName("artist").item(0).getTextContent() + "\n");

    }

}
catch (ParserConfigurationException | SAXException | IOException e)
{
    e.printStackTrace();
}

I have read for classes Container, DocumentContainer and JXPathContext, but I will be grateful for some help or for web source with specific working example.

Upvotes: 1

Views: 1387

Answers (3)

Armer B.
Armer B.

Reputation: 772

Yes I read for JxPath from few hours and I now understand the logic of this API

Much thanks for the answers. Here some code form me

public class Main {
    private final static Logger log = Logger.getLogger(Main.class);

    public static void main(String[] args) {

        PropertyConfigurator.configure("log4j.properties");

        File file = new File("students.xml");
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        try
        {
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(file);

            NodeList nList = doc.getElementsByTagName("cd");
            for(int j = 0; j<nList.getLength(); j++){

                Element element = (Element)nList.item(j);

               JXPathContext context = JXPathContext.newContext(element);
               log.debug(context.getValue("company/address/city[2]"));

            }

        }
        catch (ParserConfigurationException | SAXException | IOException e)
        {
            e.printStackTrace();
        }

    }

Upvotes: 0

G_H
G_H

Reputation: 11999

Are you sure JXPath is what you need? JXPath is an Apache library to use XPath expressions on things that aren't necessarily XML, like Java object trees or maps. If you've created a DOM from your XML, you may as well use the default Java XPath implementation on it. See here: https://docs.oracle.com/javase/7/docs/api/javax/xml/xpath/XPathFactory.html. In fact, JXpath would work against you here, because DOM has a tree of objects like Element and Text with metadata like the element name. So instead of getting an expression like //cd/artist you get something like //*[@tagName='cd']/childNodes[@tagName='artist'].

Now, if you for some reason have to be able to use XPath expressions on something that might either be a Java object tree, or a DOM, without knowing it up-front, in that case JXPath would be a good use-case in the way beckyang described in their answer: by using the JXPath DocumentContainer to access the document.

Upvotes: 1

Beck Yang
Beck Yang

Reputation: 3024

Here is the example that do similar work as yours.

File file = new File("Files/catalog.xml");
DocumentContainer dc = new DocumentContainer(file.toURI().toURL());
JXPathContext ctx = JXPathContext.newContext(dc);
Iterator iter = ctx.iterate("//cd/artist");
//In this case, following API will return DOM object
//Iterator iter = ctx.selectNodes("//cd/artist").iterator();
while (iter.hasNext()) {
    System.out.println(iter.next());//object type is String
}

Upvotes: 3

Related Questions