读取具有多个属性的Java XML文件

时间:2014-08-15 16:19:22

标签: java xml

这是我正在处理的XML文件:

<book>
    <chapter index="1" name="Chapter 2">
        <verse index="1" text="First Line" />
        <verse index="2" text="Second Line" />
        <verse index="3" text="Third Line" />
    </chapter>
    <chapter index="1" name="Chapter 2">
        <verse index="1" text="First Line" />
        <verse index="2" text="Second Line" />
        <verse index="3" text="Third Line" />
    </chapter>
</book>

根据发布的回答How can I read Xml attributes using Java?

,这是我拼命尝试的内容
import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;


public class Main
{
    public static void main (String[] args)
    {
        try
        {
            File fXmlFile = new File("book.xml");
             DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
             DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
             Document doc = dBuilder.parse(fXmlFile);
             doc.getDocumentElement().normalize();

             System.out.println("Verse: " +
                     doc.getDocumentElement().getElementsByTagName("chapter").item(0).getChildNodes().item(0).getAttributes().getNamedItem("text").getNodeValue());

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

我试图打印每章的第一节,但得到了空指针异常

4 个答案:

答案 0 :(得分:2)

您正在使用的API将标记之间的空格视为单独的节点。如果使用以下代码打印第一章子节点的节点名称:

NodeList lst = doc.getDocumentElement().getElementsByTagName("chapter").item(0).getChildNodes();

for (int i = 0; i < lst.getLength(); i++) {
    System.out.println(lst.item(i).getNodeName());
}

你会得到:

 
#text
verse
#text
verse
#text
verse
#text

这意味着索引0处的节点不是经文节点,而是一个文本节点,它不包含导致NPE的属性,因为您尝试调用不存在的属性对象的方法(null)。 / p>

如果你删除节点之前的空格,如下所示:

<book>
    <chapter index="1" name="Chapter 2"><verse index="1" text="First Line" />
...

,一切正常。

但是你最好使用getElementsByTagName("verse")来获取经文节点,这是节的子节点:

System.out.println("Verse: "
                    + ((Element)doc.getDocumentElement().getElementsByTagName("chapter").item(0)).getElementsByTagName("verse").item(0).getAttributes().getNamedItem("text").getNodeValue());

答案 1 :(得分:1)

您可以选择使用dom4j的可能性。它很直接

直接来自dom4j

   public void treeWalk(Document document) {
        treeWalk( document.getRootElement() );
    }

    public void treeWalk(Element element) {
        for ( int i = 0, size = element.nodeCount(); i < size; i++ ) {
            Node node = element.node(i);
            if ( node instanceof Element ) {
                treeWalk( (Element) node );
            }
            else {
                // do something....
            }
        }
    }

然后您需要做的就是通过添加条件来选择属性,例如:

 ....
 if ( node instanceof Element ) {
    //condition goes here:: e.g.
    if(node.getParent().getName().equals("chapter") && node.getName().equals("verse"){
       if (node.attribute("index").getData().toString().equals("1"))
          System.out.println(node.attribute(text).getDate().toString());
    }
    treeWalk( (Element) node );
 }

输出:

First Line
First Line

答案 2 :(得分:0)

你可以这样阅读每章的第一节:

         NodeList chapters = doc.getElementsByTagName("chapter");

         for(int i=0;i < chapters.getLength();i++) {
             Element chapter = (Element) chapters.item(i);
             System.out.println("Chapter = " + chapter.getAttribute("name"));
             Element verse = (Element) chapter.getElementsByTagName("verse").item(0);
             System.out.println(verse.getAttribute("text"));
         }

答案 3 :(得分:0)

NodeList listOfChapter = doc.getElementsByTagName("chapter");

NodeList listofVerse = doc.getDocumentElement().getElementsByTagName("chapter").item(0).getChildNodes(); 

for (int j = 0; j < listOfChapter.getLength(); j++) {
    for (int i = 0; i < listofVerse.getLength() / listOfChapter.getLength(); i++) {
        Element chapter = (Element) listOfChapter.item(j);
        System.out.println("Chapter = " + chapter.getAttribute("name"));
        System.out.println("Index: " + ((Element) doc.getDocumentElement().getElementsByTagName("chapter").item(j)).getElementsByTagName("verse").item(i).getAttributes().getNamedItem("index").getNodeValue());
        System.out.println("Verse: " + ((Element) doc.getDocumentElement().getElementsByTagName("chapter").item(j)).getElementsByTagName("verse").item(i).getAttributes().getNamedItem("text").getNodeValue());
    }
}