1

I'm parsing my XML File in Java with the DOM Parser/Builder. For one part of my XML Tagname it's working fine. But when I try to parse anothe Tagname, it's getting worse, because the Tagname is also used in other Tags.

XML File:

<RootTag>
  <humans>
    <human>
      <name>Max</name>
      <age>22</age>
      <friends>
        <friend>
          <name>Peter</name>
          <adress>
            <street>Way down 1</street>
          </adress>
        </friend>
        <friend>
          <name>Kevin</name>
          <adress>
            <street>Way left 2</street>
          </adress>
        </friend>
      </friends>
    </human>
    <human>
      <name>Justin</name>
      <age>22</age>
      <friends>
        <friend>
          <name>Georg</name>
          <adress>
            <street>Way up 1</street>
          </adress>
        </friend>
      </friends>
    </human>
  </humans>
  <friend>
    <friends>
      <name>Max</name>
      <numberFriends>2</numberFriends>
    </friends>
    <friends>
      <name>Justin</name>
      <numberFriends>1</numberFriends>
    </friends>
  </friend>
</RootTag>

Java:

public static void parse() throws ParserConfigurationException, IOException, SAXException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);
    factory.setIgnoringElementContentWhitespace(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    File file = new File("humanFriends.xml");
    Document doc = builder.parse(file);

    NodeList humanL = doc.getElementsByTagName("human");
    for (int j = 0; j < humanL.getLength(); j++) {
        Node humanN = humanL.item(j);
        if (humanN.getNodeType() == Node.ELEMENT_NODE) {
            Element humanE = (Element) humanN;
            String name = humanE.getElementsByTagName("name").item(0).getTextContent();
            String vehicleId = humanE.getElementsByTagName("age").item(0).getTextContent();
        ... 
        }

    NodeList friendsL = doc.getElementsByTagName("friends");
    for (int j = 0; j < friendsL.getLength(); j++) {
        Node friendsN = friendsL.item(j);
        if (friendsN.getNodeType() == Node.ELEMENT_NODE) {
            Element friendsE = (Element) friendsN;
            String name = friendsE.getElementsByTagName("name").item(0).getTextContent();
            String vehicleId = friendsE.getElementsByTagName("numberFriends").item(0).getTextContent();

        here I'm getting error because parser take also friends from human Tag... 
        }
} 

Is it possible to parse it like hierarchically or only tagsnames in specific childnodes? And is it possible to parse XML even though same tagnames in diffrent Nodes or is it a bad structur for XML?

2
  • With getElementsByTagName() you get all elements with this name regardless of their hierarchy in your XML. Use XPath to get elements like /RootTag/friend/friends/numberFriends or /RootTag/humans/human/friends/friend. Search for a tutorial or start with this: baeldung.com/java-xpath Commented Jan 10, 2019 at 16:08
  • ..it should be working, seems like you tangled in your loop somewhat.. Commented Jan 10, 2019 at 16:10

1 Answer 1

1

Element.getElementsByTagName("foo") returns all descendant elements (of the current element, with the given tag-/element name). In your code+sample this just throws a nasty NPE, because the first friends elements don't have a numberFriends inside.

Now you can:

  1. catch the NullPointerException (or otherwise test, whether you are in the correct element ...it's not my favorite approach, not clean, but quite pragmatic, short, and working).
  2. "drill down" into the xml structure, to pick the right things for you. (So, not obtain getElementsByTagName() ...from the (doc) root element, but from according sub-elements.) :

( for 2.) Assuming, you want names+ages of all //humans/human (<- XPATH) elements and the name+numberFriends from all //friend/friends elements, you'd do something like:

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
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, IOException, SAXException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(true);
        factory.setIgnoringElementContentWhitespace(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        File file = new File("humanFriends.xml");
        Document doc = builder.parse(file);

        NodeList humansL = doc.getElementsByTagName("humans");
        //System.out.println(humansL.getLength());
        for (int i = 0; i < humansL.getLength(); i++) {
            Node humansN = humansL.item(i);
            if (humansN.getNodeType() == Node.ELEMENT_NODE) {
                NodeList humanL = ((Element) humansN).getElementsByTagName("human");
                // System.out.println(humanL.getLength());
                for (int j = 0; j < humanL.getLength(); j++) {
                    Node humanN = humanL.item(j);
                    if (humanN.getNodeType() == Node.ELEMENT_NODE) {
                        Element humanE = (Element) humanN;
                        String name = humanE.getElementsByTagName("name").item(0).getTextContent();
                        String age= humanE.getElementsByTagName("age").item(0).getTextContent();
                        System.out.println(name);
                        System.out.println(age);
                    }
                }
            }
        }

        NodeList friendsL = doc.getElementsByTagName("friend");
        // System.out.println(friendsL.getLength());
        for (int i = 0; i < friendsL.getLength(); i++) {
            Node friendsN = friendsL.item(i);
            if (friendsN.getNodeType() == Node.ELEMENT_NODE) {
                NodeList friendL = ((Element) friendsN).getElementsByTagName("friends");
                // System.out.println(friendL.getLength());
                for (int j = 0; j < friendL.getLength(); j++) {
                    Node friendN = friendL.item(j);
                    if (friendN.getNodeType() == Node.ELEMENT_NODE) {
                        Element friendE = (Element) friendN;
                        String name = friendE.getElementsByTagName("name").item(0).getTextContent();
                        System.out.println(name);
                        String numberFriends = friendE.getElementsByTagName("numberFriends").item(0).getTextContent();
                        System.out.println(numberFriends);
                    }
                }
            }
        }
    }
}

Please vary the values in your (test) "humanFriends.xml" somewhat, especially to recognize problems in ambiguous tag names;)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.