Loop through all elements in XML using NodeList

java, parsing, xml

Solution

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document dom = db.parse("file.xml");
    Element docEle = dom.getDocumentElement();
    NodeList nl = docEle.getChildNodes();
    int length = nl.getLength();
    for (int i = 0; i < length; i++) {
        if (nl.item(i).getNodeType() == Node.ELEMENT_NODE) {
            Element el = (Element) nl.item(i);
            if (el.getNodeName().contains("staff")) {
                String name = el.getElementsByTagName("name").item(0).getTextContent();
                String phone = el.getElementsByTagName("phone").item(0).getTextContent();
                String email = el.getElementsByTagName("email").item(0).getTextContent();
                String area = el.getElementsByTagName("area").item(0).getTextContent();
                String city = el.getElementsByTagName("city").item(0).getTextContent();
            }
        }
    }

Iterate over all children and `nl.item(i).getNodeType() == Node.ELEMENT_NODE` is used to filter text nodes out. If there is nothing else in XML what remains are staff nodes.

For each node under stuff (name, phone, email, area, city)

 el.getElementsByTagName("name").item(0).getTextContent(); 

`el.getElementsByTagName("name")` will extract the "name" nodes under stuff, `.item(0)` will get you the first node and `.getTextContent()` will get the text content inside.

Edit: Since we have jackson I would do this in a different way. Define a pojo for the object:

public class Staff {
    private String name;
    private String phone;
    private String email;
    private String area;
    private String city;
...getters setters
}

Then using jackson:

    JsonNode root = new XmlMapper().readTree(xml.getBytes());
    ObjectMapper mapper = new ObjectMapper();
    root.forEach(node -> consume(node, mapper));



private void consume(JsonNode node, ObjectMapper mapper) {
    try {
        Staff staff = mapper.treeToValue(node, Staff.class);
        //TODO your job with staff
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
}

Problem

I want to loop through all elements in a piece of XML printing each one. My problem is that I keep getting a null pointer exception after the `staff1` tag, i.e. `john 465456433 gmail1 area1 city1` This my Java code to print all elements in an xml file: ``` File fXmlFile = new File("file.xml"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(fXmlFile); doc.getDocumentElement().normalize(); System.out.println("Root element :" + doc.getDocumentElement().getNodeName()); NodeList nList = doc.getElementsByTagName("*"); System.out.println("----------------------------"); Node n=null; Element eElement=null; for (int i = 0; i < nList.getLength(); i++) { System.out.println(nList.getLength()); n= nList.item(i); System.out.println("\nCurrent Element :" + n.getNodeName()); if (n.getNodeType() == Node.ELEMENT_NODE) { eElement = (Element) n.getChildNodes(); System.out.println("\nCurrent Element :" + n.getNodeName()); name = eElement.getElementsByTagName("name").item(i).getTextContent(); //here throws null pointer exception after printing staff1 tag phone = eElement.getElementsByTagName("phone").item(i).getTextContent(); email = eElement.getElementsByTagName("email").item(i).getTextContent(); area = eElement.getElementsByTagName("area").item(i).getTextContent(); city = eElement.getElementsByTagName("city").item(i).getTextContent(); } n.getNextSibling(); } ``` XML File: ``` <?xml version="1.0"?> <company> <staff1> <name>john</name> <phone>465456433</phone> <email>gmail1</email> <area>area1</area> <city>city1</city> </staff1> <staff2> <name>mary</name> <phone>4655556433</phone> <email>gmail2</email> <area>area2</area> <city>city2</city> </staff2> <staff3> <name>furvi</name> <phone>4655433</phone> <email>gmail3</email> <area>area3</area> <city>city3</city> </staff3> </company> ``` Expected Output: ``` john 465456433 gmail1 area1 city1 mary 4655556433 gmail2 area2 city2 furvi 4655433 gmail3 area3 city3 ```

Original source