Java Integration
Transform Anything with Java
Reading XML using DOM with XPath Expression
1. We will start this exercise by refactoring our previous example. Here is the link
2. We will add an additional argument to the getDataFromXML(), a string named xpathXpression
3. Now we will retrieve the NodeList using XPATH. We have libraries that we can use from javax.xml.xpath.
4. This goes by the following steps.
-
Create a factory object using XPathFactory class.
-
Create a XPath object using the factory.
-
Create an XPathExpression using the xpath object and the expression that we received as the argument.
-
Evaluate the NodeList using the xpath expression.
XPathFactory xfactory = XPathFactory.newInstance();
XPath xpath = xfactory.newXPath();
XPathExpression exp = xpath.compile(xpathXpression);
NodeList list = (NodeList) exp.evaluate(doc, XPathConstants.NODESET);
5. In the main method, when invoking the getDataFromXML() add the argument "//item[price > 100]"
List<Items> data = reader.getDataFromXML(filename, "//item[price > 100]");
Here is the final code.
readXMLDOM.java
package com.javatweaks.dom;
import java.io.IOException;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import com.javatweaks.sax.read.Items;
public class readXMLDOM {
public static void main(String[] args) throws IOException, ParserConfigurationException, XPathExpressionException {
DOMReader reader = new DOMReader();
String filename = "C:\\Users\\xxxx\\Documents\\Java_XML\\items.xml";
List<Items> data = reader.getDataFromXML(filename, "//item[price > 100]");
for (Items items : data) {
System.out.println(items.getManufacturer()+" "+ items.getId() + " "+ items.getName() +" " + items.getPrice());
}
}
}
DOMReader.java
package com.javatweaks.dom;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import com.javatweaks.sax.read.Items;
public class DOMReader {
public List<Items> getDataFromXML(String filename, String xpathXpression) throws XPathExpressionException {
List<Items> data = new ArrayList<>();
File inputFile = new File(filename);
Document doc = null;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(inputFile);
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
XPathFactory xfactory = XPathFactory.newInstance();
XPath xpath = xfactory.newXPath();
XPathExpression exp = xpath.compile(xpathXpression);
NodeList list = (NodeList) exp.evaluate(doc, XPathConstants.NODESET);
//NodeList list = doc.getElementsByTagName("item");
for (int i = 0; i < list.getLength(); i++) {
Items item = new Items();
data.add(item);
Element itemElement = (Element) list.item(i);
String idString = itemElement.getAttribute(Items.ID);
item.setId(Integer.parseInt(idString));
String content = getTextFromElement(itemElement, Items.MAN);
item.setManufacturer(content);
content = getTextFromElement(itemElement, Items.NAME);
item.setName(content);
content = getTextFromElement(itemElement, Items.PRICE);
item.setPrice(content);
}
return data;
}
public String getTextFromElement(Element itemElement, String elementName) {
Element node = (Element) itemElement.getElementsByTagName(elementName).item(0);
String content = node.getTextContent();
return content;
}
}
The output of the expression that we wanted to evaluate will be
Apple Inc 1 iPhone 5 600
Apple Inc 2 iPhone 6 700
Motorola 3 Moto X 200
Motorola 4 Moto G 450
Samsung Corp 5 Samsung S4 550
Now if we change the xpath expression to "//item[price >= 600]" the output will be
Apple Inc 1 iPhone 5 600
Apple Inc 2 iPhone 6 700
This way we have more flexiblity to read the XML file using XPATH.