【问题标题】:How to get the value of each node's first child in NodeList?如何获取NodeList中每个节点的第一个孩子的值?
【发布时间】:2016-02-16 01:26:38
【问题描述】:

我想获取每个元素的第一个子元素的元素名称和值。但我得到空值。我对 XML 很陌生,我很困惑,只是想用漂亮的字体来做一些事情。根大约有 15 个孩子,他们都称为“DEvent”,我希望我的输出是:

活动:星期三徒步旅行

事件:弓 - 狗糊!

等等

    <DNREvents>
<DEvent>
<event eid="1">Wednesday Trail Walks</event>
<date>2/03/2016</date>
<time>1-2:30 PM</time>
<description>...</description>
<location>Brown's Creek State Trail</location>
<cost>Free</cost>
<infoPhone>651-231-6968</infoPhone>
<infoEmail>LindaRadimecky@state.mn.us</infoEmail>
</DEvent>
<DEvent>
<event eid="2">BOW - Dog Mushing!</event>
<date>2/04/2016 thru 2/07/2016</date>
<time>Unknown</time>
<description>
This off the grid adventure is for those who want to actively participate in every aspect of learning to run your own small team of sled dogs through miles and miles of beautiful trails in the remote wilderness of northern Minnesota. Limited to 4 participants
</description>
<location>Grand Marais/Hovland</location>
<cost>$895</cost>
<infoPhone>218-370-0283</infoPhone>
<infoEmail>linda@points_unknown.com</infoEmail>
</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
<DEvent>...</DEvent>
</DNREvents>

我的java来显示结果-

Element DNR = root;
        NodeList EventList=DNR.getElementsByTagName("DEvent");
        for (int i=0; i< EventList.getLength();i++)
        {
            Node thisNode = EventList.item(i);
            Node child = thisNode.getFirstChild();
            String x = child.getNodeValue();
            System.out.println(thisNode+ x);
        }

【问题讨论】:

  • 什么是空? NodeList 还是单个节点?
  • 我得到 [DEvent: null]
  • 元素 DNR 不为空?
  • 元素 DNR 与节点一样显示为 [DNREvents: null]。
  • 请不要以大写字母开头的变量命名。使用驼峰式:en.wikipedia.org/wiki/CamelCase

标签: java xml dom xmlnodelist


【解决方案1】:

这是一个工作示例。您的代码中的 firstChild 是一个 #Text 节点,您需要获取该节点的 nextSibling() (因此您的事件节点毕竟不是第一个节点):

    import org.w3c.dom.*;
    import java.io.*;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.DocumentBuilder;

    File xmlFile = new File("/data/test/test.xml");
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(xmlFile);

    NodeList eventList = doc.getElementsByTagName("DEvent");
    for (int i=0; i< eventList.getLength(); i++) {
        Node thisNode = eventList.item(i);

        if(thisNode.hasChildNodes()){
            NodeList event = thisNode.getChildNodes().getFirstChild().getNextSibling();
            String eid = event.getAttributes().getNamedItem("eid");
            String value = event.getFirstChild().getNodeValue();
            System.out.println("EID: " + eid + " Value: " + value + "\n");
        }
    }

请注意,如果您不进行额外的空值检查以验证 xml 是否具有正确的子节点格式,那么此行将很脆弱。而且,这并不强制 xml 中子节点的顺序是您期望的顺序:

NodeList child = thisNode.getChildNodes().getFirstChild().getNextSibling();

话虽如此,我认为更好的实现是使用 XPath,它允许您选择所需的节点而无需手动遍历树,并且更紧凑且“故障安全”:

    XPath xpath = XPathFactory.newInstance().newXPath();
    String expression = "/DNREvents/DEvent/event";
    InputSource inputSource = new InputSource(new BufferedReader(new FileReader("/data/test/test.xml")));
    NodeList eventList = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);

    for (int i=0; i< eventList.getLength(); i++) {
        Node eventNode = eventList.item(i);

        String eid = xpath.evaluate("@eid", eventNode);
        String value = xpath.evaluate("./text()", eventNode);
        System.out.println("EID: " + eid + ", Value: " + value + "\n");
    }

【讨论】:

  • 酷!我应该使用什么值来获取每个元素名称(DEvent)?我仍然使用 'child' 或 'thisNode' 使用您的代码获得 [event: null]
  • 看看我使用 XPath 的最新更新。您可以更改表达式以满足您的需要。这是 XPath 的 JavaDoc:docs.oracle.com/javase/7/docs/api/javax/xml/xpath/…
  • 这是一个很好的例子,它使用 XPath 从 XML 中选择你想要的任何数据:viralpatel.net/blogs/java-xml-xpath-tutorial-parse-xml
  • 非常感谢!我得回到神话时代,我看到你的照片了:D
  • 好的,我更新了 DOM 示例以从事件中获取 eid 值。
猜你喜欢
  • 2011-09-07
  • 1970-01-01
  • 2015-08-06
  • 2022-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多