2012-07-25 20 views
6

ho il seguente file xml:Java Dom parser segnala un numero sbagliato di nodi figli

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

Poi sto cercando di analizzarlo con Java, ma getChildNodes riporta numero errato di nodi figlio.

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

Risultato: 3

Inoltre mi sto NPE per l'accesso ai nodi di attributi, quindi sto cercando di indovinare qualcosa sta andando storto.

risposta

3

Ci sono tre nodi figli:

  • un nodo di testo contenente un'interruzione di linea
  • un nodo di elementi (utente etichettato)
  • un nodo di testo contenente un'interruzione di linea

Quindi, quando si elaborano i nodi figlio, verificare la presenza di nodi elemento.

+4

Grazie, sai un modo per filtrare solo gli elementi in modo generico? –

4

I nodi figlio sono costituiti da elementi e nodi di testo per spazi bianchi. Dovrai controllare il tipo di nodo prima di elaborare gli attributi. Si potrebbe anche voler considerare l'utilizzo delle javax.xml.xpath API disponibili nel JDK/JRE a partire da Java SE 5.

Esempio 1

Questo esempio dimostra come a rilasciare una dichiarazione XPath contro un 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("https://stackoverflow.com/users/user", document, XPathConstants.NODE); 
     System.out.println(userElement.getAttribute("id")); 
     System.out.println(userElement.getAttribute("firstname")); 
    } 

} 

Esempio 2

L'esempio seguente mostra come rilasciare una dichiarazione XPath contro un InputSource per ottenere un nodo DOM. Questo ti evita di dover analizzare personalmente l'XML in un 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("https://stackoverflow.com/users/user", inputSource, XPathConstants.NODE); 
     System.out.println(userElement.getAttribute("id")); 
     System.out.println(userElement.getAttribute("firstname")); 
    } 

} 
1

Devi assicurarti di avere account per il \ n 'tra i nodi, che contano per i nodi di testo. È possibile verificare che l'utilizzo di 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()); 
       } 
      } 
     } 
0

Non ho notato nessuna delle risposte che affrontano l'ultima nota su NPE quando si cerca di accedere agli attributi.

Inoltre sto ricevendo NPE per l'accesso agli attributi dei nodi, quindi suppongo che qualcosa stia andando terribilmente storto.

Dal momento che ho visto il seguente suggerimento su alcuni siti, Penso che sia un modo comune per accedere agli attributi:

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

che funziona bene se i nodi contengono sempre un attributo myProp, ma se non ha attributi, getAttributes restituirà null.Inoltre, se sono presenti attributi, ma non l'attributo myProp, getNamedItem restituirà null.

Attualmente sto usando

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 una classe di utilità, ma la vostra situazione potrebbe essere diversa.