Java Dom Parser Reporting Incorrect Number of Child Nodes

I have the following xml file:

<?xml version="1.0" encoding="UTF-8"?> <users> <user id="0" firstname="John"/> </users> 

Then I try to parse it using java, but getchildnodes reports the wrong number of child nodes.

Java Code:

 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()); 

Result: 3

I also get NPE to access the attributes of the nodes, so I assume something is terribly wrong.

+6
source share
4 answers

There are three child nodes:

  • node text containing line break
  • node element (user tagged)
  • node text containing line break

Therefore, when processing child nodes, check the element nodes.

+3
source

child nodes are composed of elements and text nodes for spaces. Before processing the attributes, you will need to check the type of node. You can also consider using the javax.xml.xpath APIs available in the JDK / JRE starting in Java SE 5.

Example 1

This example shows how to issue an XPath statement for the DOM.

 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")); } } 

Example 2

The following example shows how to issue an XPath instruction for an InputSource to get a DOM node. This saves you the trouble of parsing XML in the DOM yourself.

 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")); } } 
+4
source

You must make sure that you account for "\ n" between the nodes that are counted for text nodes. You can verify this using 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()); } } } 
+1
source

I did not notice any of the answers regarding your last note on NPE when trying to access attributes.

I also get NPE to access the attributes of the nodes, so I assume something is terribly wrong.

Since I saw the following sentence on multiple sites, I assume this is the usual way to access attributes:

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

which works fine if the nodes always contain the myProp attribute, but if it has no attributes, getAttributes returns null. Also, if there are attributes but not the myProp attribute, getNamedItem returns null.

I am currently using

 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; } 

in the utility class, but your mileage may vary.

0
source

Source: https://habr.com/ru/post/921301/


All Articles