有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何获取节点列表中每个节点的第一个子节点的值?

我想获取每个元素的第一个子元素的名称和值。但我得到的是空值。我对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);
        }

共 (1) 个答案

  1. # 1 楼答案

    下面是一个工作示例。代码中的第一个子节点是#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");
            }
        }
    

    请注意,如果不执行额外的null检查来验证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");
        }