如何只获取XML文档中第一个元素的直接子元素?

时间:2015-12-17 15:12:35

标签: java xml

我正在研究一个XML示例,以便更好地理解DOM和XML。我有一个带汽车的XML文档,其中我想获得第一批汽车节点。

我也想做这个通用的,没有给出特定的标签名称(通过标签找到元素"超级跑车" /" luxurycars" ...)。更像是"给我所有来自汽车的直接子节点" - > "超级跑车,超级跑车,豪华车"。

因此,为了理解结构,我编写了以下代码。

但输出让我困惑:

  • 为什么Nodelist长度为7?它是" [汽车],[超级跑车],[超级跑车的内容],[超级跑车],[超级跑车的内容]"?我不能设法把元素拿出去看看。
  • 为什么有4个空的"当前元素:"?
  • 为什么是第一个NodeName" #text"而不是" sportcars",哪来了?

我的XML文档sportcars.xml。:

     <?xml version="1.0"?>
     <cars>
        <supercars company="Ferrari">
           <carname type="formula one">Ferarri 101</carname>
           <carname type="sports car">Ferarri 201</carname>
           <carname type="sports car">Ferarri 301</carname>
        </supercars>
        <supercars company="Lamborgini">
           <carname>Lamborgini 001</carname>
           <carname>Lamborgini 002</carname>
           <carname>Lamborgini 003</carname>
        </supercars>
        <luxurycars company="Benteley">
           <carname>Benteley 1</carname>
           <carname>Benteley 2</carname>
           <carname>Benteley 3</carname>
        </luxurycars>
     </cars>

我的java文件QueryXMLFileDemo.java:

package xml;

import java.io.File;

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

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class QueryXmlFileDemo {
    public static void main(String[] args) {
        try {
            File inputFile = new File("sportcars.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(inputFile);
            doc.getDocumentElement().normalize();
            Node n = doc.getFirstChild();
            NodeList nL = n.getChildNodes();
            System.out.println("Nodelist length: " + nL.getLength());
            for (int i = 0; i < nL.getLength(); i++) {
                Node temp = nL.item(i);
                System.out.println("Current Element: " + temp.getTextContent());
                System.out.println("NodeName: " + temp.getNodeName());
                System.out.println("Root Element: " + doc.getDocumentElement().getNodeName());
                NodeList nList = doc.getElementsByTagName("supercars");
            }
        } catch (Exception e) {
        }
    }
}

输出:

Nodelist length: 7
Current Element: 

NodeName: #text
Current Element: 
      Ferarri 101
      Ferarri 201
      Ferarri 301

NodeName: supercars
Current Element: 

NodeName: #text
Current Element: 
      Lamborgini 001
      Lamborgini 002
      Lamborgini 003

NodeName: supercars
Current Element: 

NodeName: #text
Current Element: 
      Benteley 1
      Benteley 2
      Benteley 3

NodeName: luxurycars
Current Element: 

NodeName: #text

那么,我怎么才能打印节点&#34;超级跑车,超级跑车,豪华车&#34;没有别的吗?

3 个答案:

答案 0 :(得分:1)

检索节点的更好方法是使用XPath或XQuery;继承更容易推理

答案 1 :(得分:1)

你得到#34;#text&#34;在输出中因为在XML中元素之间有文本节点,即使这些只是像换行符或缩进这样的空白空间。有关不同的可能节点类型,请参阅http://localhost:61915/Albums

当您打印节点getTextContent时,它会打印节点及其子节点the Node Javadoc

如果您只想忽略#text节点(或任何其他节点),您可以在循环中检查您正在处理的节点。在你的情况下,它将是这样的:

if (Node.ELEMENT_NODE != temp.getNodeType()) {
    continue;
}

答案 2 :(得分:0)

我找到了解决方案,但我也不得不承认,我的问题过于宽泛和令人困惑。因此,我发布了解决问题和希望的方法,这清除了我之前所要求的内容。

package xml;

import javax.xml.parsers.DocumentBuilder;
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class QueryXmlFileDemo {

    public static void main(String[] args) {
        try {
            File inputFile = new File("sportcars.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document inputDocument = dBuilder.parse(inputFile);
            inputDocument.getDocumentElement().normalize();
            Node carsNode = inputDocument.getFirstChild();
            NodeList carsNodeList = carsNode.getChildNodes();
            for (int i = 0; i < carsNodeList.getLength(); i++) {
                Node carTypes = carsNodeList.item(i);
                // hides the #text-entries
                if (Node.ELEMENT_NODE != carTypes.getNodeType()) {
                    continue;
                }
                System.out.println("CarType: " + carTypes.getNodeName());
            }
        } catch (Exception e) {
        }
    }
}

输出:

CarType: supercars
CarType: supercars
CarType: luxurycars

所以不知道我的XML文档的属性我可以得到第一级&#34;节点 - <cars>中的第一个节点:<supercars><supercars><luxurycars>