everyone!
I’m facing the problem of getting data to create an object from the following XML file.
<staff>
<employee>
<id>1</id>
<firstName>John</firstName>
<lastName>Smith</lastName>
<country>USA</country>
<age>25</age>
</employee>
<employee>
<id>2</id>
<firstName>Inav</firstName>
<lastName>Petrov</lastName>
<country>RU</country>
<age>23</age>
</employee>
I can't get the value of the attribute through the method getAttributeValue().
all I got was to get the value in the format String with method getTextContent.
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = documentBuilder.parse("data.xml");
Node root = document.getDocumentElement();
NodeList staff = root.getChildNodes();
for (int i = 0; i < staff.getLength(); i ) {
Node employee = staff.item(i);
if (employee.getNodeType() != Node.TEXT_NODE) {
NodeList employeeProps = employee.getChildNodes();
for (int j = 0; j < employeeProps.getLength(); j ) {
Node employeeProp = employeeProps.item(j);
if (employeeProp.getNodeType() != Node.TEXT_NODE)
employeeProp.getTextContent();
// **TODO Employee?**
}
}
tell me please how you can implement this idea, and still get the value to create an object of the class Employee?
CodePudding user response:
I like to use XPath for this kind of things:
Element root = document.getDocumentElement();
NodeList staff = root.getChildNodes();
for (int i = 0; i < staff.getLength(); i ) {
Node employee = staff.item(i);
System.out.println(eval(employee, "id"));
System.out.println(eval(employee, "firstName")
" " eval(employee, "lastName"));
}
public static String eval(Node node, String expr)
throws XPathExpressionException {
return (String)eval(node, expr, XPathConstants.STRING);
}
public static Node evalNode(Node node, String expr)
throws XPathExpressionException {
return (Node)eval(node, expr, XPathConstants.NODE);
}
private static Object eval(Node node, String expr, QName type)
throws XPathExpressionException {
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
return xpath.evaluate(expr, node, type);
}
UPDATE: Or rather:
Element root = document.getDocumentElement();
NodeList staff = evalNodes(root, "employee");
for (int i = 0; i < staff.getLength(); i ) {
Node employee = staff.item(i);
String id = eval(employee, "id");
System.out.println(id);
System.out.println(eval(employee, "firstName")
" " eval(employee, "lastName"));
}
public static String eval(Node node, String expr)
throws XPathExpressionException {
return (String)eval(node, expr, XPathConstants.STRING);
}
public static Node evalNode(Node node, String expr)
throws XPathExpressionException {
return (Node)eval(node, expr, XPathConstants.NODE);
}
public static NodeList evalNodes(Node node, String expr)
throws XPathExpressionException {
return (NodeList)eval(node, expr, XPathConstants.NODESET);
}
private static Object eval(Node node, String expr, QName type)
throws XPathExpressionException {
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
return xpath.evaluate(expr, node, type);
}
CodePudding user response:
I would highly recommend having a look at Introduction to JAXB and How XPath Works probably wouldn't hurt
It's been a REALLY long time since I had to do any XML or xPath related work, so there may be some enhancements that could be applied, but the basic idea might look something like...
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.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Test {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
new Test();
}
public Test() throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = documentBuilder.parse("data.xml"));
String expression = "/staff/employee";
XPath xPath = XPathFactory.newInstance().newXPath();
Object result = xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
List<Employee> employees = new ArrayList<>(25);
NodeList nodes = (NodeList) result;
for (int index = 0; index < nodes.getLength(); index ) {
Node node = nodes.item(index);
Employee employee = employeeFrom(node);
employees.add(employee);
}
System.out.println(employees.size());
for (Employee emp : employees) {
System.out.println("[" emp.getId() "] " emp.getFirstName() " " emp.getLastName() "; " emp.getCountry() "; " emp.getAge());
}
}
protected Employee employeeFrom(Node node) throws XPathExpressionException {
XPath xPath = XPathFactory.newInstance().newXPath();
int id = ((Double)xPath.compile("id/text()").evaluate(node, XPathConstants.NUMBER)).intValue();
String firstName = (String)xPath.compile("firstName/text()").evaluate(node, XPathConstants.STRING);
String lastName = (String)xPath.compile("lastName/text()").evaluate(node, XPathConstants.STRING);
String country = (String)xPath.compile("country/text()").evaluate(node, XPathConstants.STRING);
int age = ((Double)xPath.compile("age/text()").evaluate(node, XPathConstants.NUMBER)).intValue();
return new Employee(id, firstName, lastName, country, age);
}
public class Employee {
private int id;
private String firstName;
private String lastName;
private String country;
private int age;
public Employee(int id, String firstName, String lastName, String country, int age) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.country = country;
this.age = age;
}
public int getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getCountry() {
return country;
}
public int getAge() {
return age;
}
}
}
Now, the code is making some assumptions about the structure and isn't doing any kind of error handling, so you might need to look into that as well.