如何使用DOM API访问XML节点的值

时间:2014-04-14 12:03:22

标签: java xml parsing dom

我试图使用Dom解析器访问XML文档中的某些值,我收到一个奇怪的空指针异常错误。 我正在使用的代码是:

    import java.io.File;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;

    public class readXML {

    public static void main(String[] args) {
    File file = new File("C:\\Users\\manolaki\\Desktop\\assets.xml");
    try {
      DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      Document doc = builder.parse(file);
      doc.getDocumentElement().normalize();

            Node node = doc.getElementsByTagName("assets").item(0).getChildNodes().item(1).getChildNodes().item(1).getAttributes().getNamedItem("src");

            String boo = node.getNodeValue();

            System.out.println("Name is " + boo);

      }
    catch (Exception e) {
      e.printStackTrace();
      }
   }
}

我正在使用的xml:

 <?xml version="1.0" encoding="UTF-8"?>
<xml>

<assets>
<sprite>
    <img src="menu.png"/>
</sprite>
<sprite>
    <img src="background.png"/>
</sprite>
<sprite>
    <img src="buttons.png"/>
</sprite>
<sprite>
    <img src="animals.png"/>
</sprite>
<sprite>
    <img src="cycles.png"/>
</sprite> 
<sprite>
    <img src="texts.mp3"/>
</sprite>
<sprite>
    <img src="music.mp3"/>
</sprite>
<sprite>
    <img src="click.mp3"/>
</sprite>
<sprite>
    <img src="swipe.mp3"/>
</sprite>
<sprite>
    <img src="dog.mp3"/>
</sprite>
</assets>

<assets>
<sprite>
    <img src="mehnu.png"/>
</sprite>
<sprite>
    <img src="background.png"/>
</sprite>
<sprite>
    <img src="buttons.png"/>
</sprite>
<sprite>
    <img src="animals.png"/>
</sprite>
<sprite>
    <img src="cycles.png"/>
</sprite> 
<sprite>
    <img src="texts.mp3"/>
</sprite>
<sprite>
    <img src="music.mp3"/>
</sprite>
<sprite>
    <img src="click.mp3"/>
</sprite>
<sprite>
    <img src="swipe.mp3"/>
</sprite>
<sprite>
    <img src="dog.mp3"/>
</sprite>
 </assets>

 </xml>

代码工作正常,它在控制台打印出“menu.png”。问题是,虽然我可以使用第一个“Item()”部分浏览资产节点,但如果我尝试更改第二个“item()”以浏览精灵,则会打印出空指针异常错误。例如,如果我使用它,它可以工作:

                Node node = doc.getElementsByTagName("assets").item(1).getChildNodes().item(1).getChildNodes().item(1).getAttributes().getNamedItem("src");

但不是我用的时候

            Node node = doc.getElementsByTagName("assets").item(0).getChildNodes().item(2).getChildNodes().item(1).getAttributes().getNamedItem("src");

我认为这有点奇怪..鉴于eclipse没有发现任何错误。 任何帮助,将不胜感激。感谢

2 个答案:

答案 0 :(得分:1)

你的问题是NodeList的item(0)是一个文本节点,而文本节点没有子节点,这是抛出NullPointerException的地方。

尝试将此添加到您的代码中以验证:

Node child0 = doc.getElementsByTagName("assets").item(0).getChildNodes().item(0);
if (child0.getNodeType() == Node.TEXT_NODE) {
    System.out.println("child node is text");
}

所以请记住,在迭代NodeList时需要检查每个节点的类型。

在您的情况下,您的奇数编号的子项是文本节点,您的偶数子项是元素。试试这个:

NodeList nodes = doc.getElementsByTagName("assets").item(0).getChildNodes();
for ( int x = 0; x < nodes.getLength(); x++ ) {
    Node node = nodes.item(x);
    if (node.getNodeType() == Node.TEXT_NODE) {
        System.out.println(x + " text");
    } else if (node.getNodeType() == Node.ELEMENT_NODE) {
        String nodeName = node.getNodeName();

        System.out.println(x + " Node: " + nodeName);
    }
}

输出:

0 text
1 Node: sprite
2 text
3 Node: sprite
4 text
5 Node: sprite
...

您可能需要查看Dr. Dobb的this article,它有一些很好的示例代码,您可以从中为这种低级DOM解析创建一些便捷方法。

答案 1 :(得分:0)

对于更简单的API,请查看Xsylum。使用DOM:

String src = Xsylum.elementFor(xmlFile).get("sprite").get("img").attribute("src");

或者使用XPath:

String src = Xsylum.elementFor(xmlFile).value("//sprite[1]/img/@src");