遍历DOM树以获取(名称,值)属性对和叶节点

时间:2011-08-26 03:59:48

标签: java dom

我想遍历DOM中的XML文件,以便检索所有的(名称,值)对:

  1. 属性名称和值;
  2. 所有叶节点名称及其文本内容;
  3. 所以给出以下XML文件作为示例:

    <?xml version="1.0" encoding="UTF-8"?>
    <title text="title1">
        <comment id="comment1">
            <data> abcd </data>
            <data> efgh </data>
        </comment>
        <comment id="comment2">
            <data> ijkl </data>
            <data> mnop </data>
            <data> qrst </data>
        </comment>
    </title>
    

    我想要的名称值对是:

    text=title1
    id=comment1
    data=abcd
    data=efgh
    id=commment2
    data=ijkl
    data=mnop
    data=qrst
    

2 个答案:

答案 0 :(得分:4)

更简单的解决方案可能是使用XPath提取所有名称值对,如下例所示。您也可以跳过DOM构造并直接在InputSource上调用evaluate。 XPath表达式

//@* | //*[not(*)]

匹配所有属性的并集以及所有没有任何子节点的节点。

import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class Test {

    private static final String xml = "<title text='title1'>\n"
            + "  <comment id='comment1'>\n"
            + "    <data> abcd </data>\n"
            + "    <data> efgh </data>\n"
            + "  </comment>\n"
            + "  <comment id='comment2'>\n"
            + "    <data> ijkl </data>\n"
            + "    <data> mnop </data>\n"
            + "    <data> qrst </data>\n"
            + "  </comment>\n"
            + "</title>\n";

    public static void main(String[] args) throws Exception {
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(xml)));

        XPathFactory xpf = XPathFactory.newInstance();
        XPath xp = xpf.newXPath();
        NodeList nodes = (NodeList)xp.evaluate("//@* | //*[not(*)]", doc, XPathConstants.NODESET);

        System.out.println(nodes.getLength());

        for (int i=0, len=nodes.getLength(); i<len; i++) {
            Node item = nodes.item(i);
            System.out.println(item.getNodeName() + " : " + item.getTextContent());
        }
    }
}

答案 1 :(得分:2)

如下:

    String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
        "<title text=\"title1\">\n" +
        "    <comment id=\"comment1\">\n" +
        "        <data> abcd </data>\n" +
        "        <data> efgh </data>\n" +
        "    </comment>\n" +
        "    <comment id=\"comment2\">\n" +
        "        <data> ijkl </data>\n" +
        "        <data> mnop </data>\n" +
        "        <data> qrst </data>\n" +
        "    </comment>\n" +
        "</title>\n";

    try {
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(xml)));

        DocumentTraversal traversal = (DocumentTraversal) doc;

        NodeIterator iterator = traversal.createNodeIterator(
          doc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);

        for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) {
            //System.out.println("Element: " + ((Element) n).getTagName());
            String tagname = ((Element) n).getTagName();
            if(tagname.equals("title")) {
                System.out.println("text=" + ((Element)n).getAttribute("text"));
            }
            else if(tagname.equals("comment")) {
                System.out.println("id=" + ((Element)n).getAttribute("id"));
            }
            else if(tagname.equals("data")) {
                System.out.println("data=" + ((Element)n).getTextContent());
            }
            else {
                System.out.println("Unhandled element");
            }
        }

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

好的,所以你对此不满意,怎么样:

 String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
        "<title text=\"title1\">\n" +
        "    <comment id=\"comment1\">\n" +
        "        <data> abcd </data>\n" +
        "        <data> efgh </data>\n" +
        "    </comment>\n" +
        "    <comment id=\"comment2\">\n" +
        "        <data> ijkl </data>\n" +
        "        <data> mnop </data>\n" +
        "        <data> qrst </data>\n" +
        "    </comment>\n" +
        "</title>\n";

    try {
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(xml)));

        DocumentTraversal traversal = (DocumentTraversal) doc;

        NodeIterator iterator = traversal.createNodeIterator(
          doc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);

        for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) {
            //System.out.println("Element: " + ((Element) n).getTagName());
            String tagname = ((Element) n).getTagName();

            NamedNodeMap map = ((Element)n).getAttributes();
            if(map.getLength() > 0) {

                for(int i=0; i<map.getLength(); i++) {
                    Node node = map.item(i);
                    System.out.println(node.getNodeName() + "=" + node.getNodeValue());
                }
            }
            else {
                System.out.println(tagname + "=" + ((Element)n).getTextContent());
            }
        }

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