我在从XML读取数据并将其加载到数组中时遇到一些问题。这是我的代码:
private void LoadMap(字符串路径({DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance((;文档文档=空;
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();
}
}
问题是您忽略了这样一个事实,即在输入XML中只有空白的文本节点,当使用getChildNodes().item(i)
时,这些节点占据了索引位置。必须检查每个节点类型并忽略非元素节点,以便只处理所需的节点。
根据您的输入,我可以看出每行标记之间有一个空白节点,因此
column = row.getChildNodes().item(k);
其中i==1,返回一个文本节点。由于文本节点没有子节点,因此column
此时为空,从而导致NPE。
这也意味着您不能盲目地使用<tileset>
标记中的计数作为循环边界。在处理每个节点类型之前,必须对其进行测试,并对实际处理的节点进行计数,直到达到预期的总数(顺便说一句,这是错误的;共有50行50列(。
查看NullPointerException
javadocs,
当应用程序尝试在对象为的情况下使用null必需。
其中包括:
- 调用null的实例方法对象
- 访问或修改空对象的字段
- 采取null的长度,就好像它是一个数组一样
- 访问或修改的插槽null,就好像它是一个数组一样
- 投掷null,就好像它是一个Throwable值一样
- 应用程序应该抛出此类以指示其他非法使用null对象
以上6项中的任何一项都可能是您在代码中可能犯的错误。