2

I'm having some problems reading data from XML and load it into an array. This is the code I have:

private void LoadMap(String path) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ( ); Document document = null;

try {
    DocumentBuilderFactory builder = DocumentBuilderFactory.newInstance();
    builder.setIgnoringElementContentWhitespace(true);
    document = builder.newDocumentBuilder().parse(path);

    Element Map = document.getDocumentElement();
    Node nodeTileset = Map.getElementsByTagName("tileset").item(0);
    Node nodeData = Map.getElementsByTagName("data").item(0);

    NamedNodeMap attribTileset = nodeTileset.getAttributes();
    layers = Integer.parseInt(attribTileset.getNamedItem("layers").getNodeValue());
    width = 50;
    height = 50;
    name = Map.getAttribute("name");

    // Creamos el array y lo rellenamos con los valores
    array = new int[layers][height][width];

    Node layer, row, column;
    for(int i = 0; i < layers; i++) {
        layer = nodeData.getChildNodes().item(i);
        for(int j = 0; j < height; j++) {
            if(layer.getNodeType() != Node.TEXT_NODE) {
                row = layer.getChildNodes().item(j);
                for(int k = 0; k < width; k++) {
                    if(row.getNodeType() != Node.TEXT_NODE) {
                        column = row.getChildNodes().item(k);
                        if(column.getNodeType() != Node.TEXT_NODE) {
                            array[i][j][k] = Integer.parseInt(column.getTextContent());
                        }
                    }
                }
            }
        }
    }
}
catch(ParserConfigurationException e) {
    e.printStackTrace();
}
catch (SAXException e) {
    e.printStackTrace();
}
catch(IOException e) {
    e.printStackTrace();
}

}

2 Answers 2

1

The problem is that you have ignored the fact that there are whitespace-only text nodes in your input XML, which take up index positions when using getChildNodes().item(i). You must check each node type and ignore non-element nodes so that you process only the ones you want.

From your input, I can tell that there is a whitespace node between row each row tag, so

column = row.getChildNodes().item(k);

where i == 1, returns a text node. Since the text node has no child nodes, column is null at this point, resulting in the NPE.

This also means you can't blindly use the counts from the <tileset> tag as loop boundaries. You must test each node type before you process it and count actually processed nodes until you reach the expected totals (which are wrong, by the way; there are 50 rows and 50 columns).

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

3 Comments

Ok, thank you. I have edited the code of the main post with the new changes. Now it works fine, but it skips the non pair rows >.<U So the rows are stored, one yes, one no, one yes, etc... I don't know how to solve this.
Your loops are still using the counts from the <tileset> tag. Since there are actually more nodes present if you count the text nodes, you can't stop after seeing height row nodes and width column nodes. The for loops need to change to, for example, while(k < width), and you increment k only when handling a <col> node.
Ok thank you. With that solution now it works fine. But I didn't like the code, so I found that if I activate XML validation in java and I add a DTD information to the XML, I can skip check if there are text nodes, so I can forget him.
0

Look at the NullPointerException javadocs,

Thrown when an application attempts to use null in a case where an object is required.

These include:

  • Calling the instance method of a null object.
  • Accessing or modifying the field of a null object.
  • Taking the length of null as if it were an array.
  • Accessing or modifying the slots of null as if it were an array.
  • Throwing null as if it were a Throwable value.
  • Applications should throw instances of this class to indicate other illegal uses of the null object.

Any of the above 6 could be the mistake you might have done in your code.

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.