简体   繁体   English

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

[英]Traversing a DOM tree to get (name,value) pairs of attributes and leaf nodes

I want to traverse through an XML file in DOM for the purpose of retrieving as (name,value) pairs all: 我想遍历DOM中的XML文件,以便检索所有的(名称,值)对:

  1. Attribute names and values; 属性名称和值;
  2. All leaf node names and their text content; 所有叶节点名称及其文本内容;

So given the following XML file as an example: 因此,以下面的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>

What I want as name value pairs are: 我想要的名称值对是:

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

An easier solution might be to use XPath to extract all name value pairs as in the following example. 更简单的解决方案可能是使用XPath提取所有名称值对,如以下示例所示。 You could also skip the DOM construction and call evaluate directly on the InputSource . 您还可以跳过DOM构造并直接在InputSource上调用evaluate。 The XPath expression XPath表达式

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

matches the union of all attributes and all nodes that don't have any child nodes. 匹配所有属性的联合以及没有任何子节点的所有节点。

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());
        }
    }
}

How about something like: 怎么样的:

    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();
    }

Okay, so you weren't happy with that, how about this: 好的,所以你对此不满意,怎么样:

 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();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM