Java Dom解析器报告错误的子节点数

我有以下xml文件:

    

然后我试图用java解析它,但getchildnodes报告错误的子节点数。

Java代码:

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(this.file); document.getDocumentElement().normalize(); Element root = document.getDocumentElement(); NodeList nodes = root.getChildNodes(); System.out.println(nodes.getLength()); 

结果:3

此外,我正在获取用于访问节点属性的NPE,因此我猜测某些事情可怕的错误。

有三个子节点:

  • 包含换行符的文本节点
  • 元素节点(标记用户)
  • 包含换行符的文本节点

因此,在处理子节点时,请检查元素节点。

子节点由空格的元素和文本节点组成。 您需要在处理属性之前检查节点类型。 您可能还需要考虑使用从Java SE 5开始的JDK / JRE中提供的javax.xml.xpath API。

例1

此示例演示如何针对DOM发出XPath语句。

 package forum11649396; import java.io.StringReader; import javax.xml.parsers.*; import javax.xml.xpath.*; import org.w3c.dom.*; import org.xml.sax.InputSource; public class Demo { public static void main(String[] args) throws Exception { String xml = ""; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(new InputSource(new StringReader(xml))); XPathFactory xpf = XPathFactory.newInstance(); XPath xpath = xpf.newXPath(); Element userElement = (Element) xpath.evaluate("/users/user", document, XPathConstants.NODE); System.out.println(userElement.getAttribute("id")); System.out.println(userElement.getAttribute("firstname")); } } 

例2

以下示例演示如何针对InputSource发出XPath语句以获取DOM节点。 这样您就不必自己将XML解析为DOM。

 package forum11649396; import java.io.StringReader; import javax.xml.xpath.*; import org.w3c.dom.*; import org.xml.sax.InputSource; public class Demo { public static void main(String[] args) throws Exception { String xml = ""; XPathFactory xpf = XPathFactory.newInstance(); XPath xpath = xpf.newXPath(); InputSource inputSource = new InputSource(new StringReader(xml)); Element userElement = (Element) xpath.evaluate("/users/user", inputSource, XPathConstants.NODE); System.out.println(userElement.getAttribute("id")); System.out.println(userElement.getAttribute("firstname")); } } 

您必须确保考虑节点之间的’\ n’,它们计算文本节点。 您可以使用if(root.getNodeType() == Node.ELEMENT_NODE)

  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(this.file); document.getDocumentElement().normalize(); for(Node root = document.getFirstChild(); root != null; root = root.getNextSibling()) { if(root.getNodeType() == Node.ELEMENT_NODE) { NodeList nodes = root.getChildNodes(); System.out.println(root.getNodeName() + " has "+nodes.getLength()+" children"); for(int i=0; i 

在尝试访问属性时,我没有注意到有关NPE的最后一个注释的任何答案。

此外,我正在获取用于访问节点属性的NPE,因此我猜测某些事情可怕的错误。

由于我在一些网站上看到了以下建议,我认为这是访问属性的常用方法:

 String myPropValue = node.getAttributes().getNamedItem("myProp").getNodeValue(); 

如果节点始终包含myProp属性,则可以myProp ,但如果它没有属性,则getAttributes将返回null。 此外,如果存在属性但没有myProp属性,则getNamedItem将返回null。

我正在使用

 public static String getStrAttr(Node node, String key) { if (node.hasAttributes()) { Node item = node.getAttributes().getNamedItem(key); if (item != null) { return item.getNodeValue(); } } return null; } public static int getIntAttr(Node node, String key) { if (node.hasAttributes()) { Node item = node.getAttributes().getNamedItem(key); if (item != null) { return Integer.parseInt(item.getNodeValue()); } } return -1; } 

在公用事业类,但你的里程可能会有所不同。

Interesting Posts