Home > Back-end >  Create Arrays <Objects> From xml file
Create Arrays <Objects> From xml file

Time:10-01

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.

  • Related