我有以下xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user id="0" firstname="John"/>
</users>
然后我试图用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,因此我猜测某些内容非常糟糕。
答案 0 :(得分:4)
子节点由空格的元素和文本节点组成。您需要在处理属性之前检查节点类型。您可能还需要考虑从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 = "<?xml version='1.0' encoding='UTF-8'?><users><user id='0' firstname='John'/></users>";
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 = "<?xml version='1.0' encoding='UTF-8'?><users><user id='0' firstname='John'/></users>";
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"));
}
}
答案 1 :(得分:3)
有三个子节点:
因此,在处理子节点时,请检查元素节点。
答案 2 :(得分:1)
您必须确保考虑节点之间的'\ 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<nodes.getLength(); i++) {
Node n = nodes.item(i);
System.out.println("\t"+n.getNodeName());
}
}
}
答案 3 :(得分:0)
在尝试访问属性时,我没有注意到有关NPE的最后一个注释的任何答案。
此外,我正在获取用于访问节点属性的NPE,因此我猜测某些内容非常糟糕。
由于我在几个网站上看到了以下建议,我认为这是访问属性的常用方法:
String myPropValue = node.getAttributes().getNamedItem("myProp").getNodeValue();
如果节点始终包含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;
}
在公用事业类中,但您的里程可能会有所不同。