2012-08-26 20 views
6

Estoy intentando leer en un XML utilizando DOM en JavaIterar un NodeList que consiste algunas etiquetas con el mismo nombre usando DOM

<?xml version="1.0"?> 
<record> 
<user> 
    <name>Leo</name> 
    <email>****@****.com</email> 
     <food-list> 
      <food>Hamburgers</food> 
      <food>Fish</food> 
     </food-list> 
</user> 
</record> 

Mi solución actual es

for (int userNumber = 0; userNumber < masterList.getLength(); userNumber++) { 

      Node singleUserEntry = masterList.item(userNumber); 
      if (singleUserEntry.getNodeType() == Node.ELEMENT_NODE) { 

       org.w3c.dom.Element userEntryElement = (org.w3c.dom.Element) singleUserEntry; 



       System.out.println("name : " + getTagValue("name", userEntryElement)); 
       System.out.println("email : " +getTagValue("email", userEntryElement)); 
       NodeList foodList = userEntryElement.getElementsByTagName("food-list").item(0).getChildNodes(); 
       for(int i = 0; i < foodList.getLength(); i++){ 
        Node foodNode = foodList.item(i); 
        System.out.println("food : " + foodNode.getNodeValue()); 
       } 

private static String getTagValue(String sTag, org.w3c.dom.Element eElement) { 
    NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes(); 
    Node nValue = (Node) nlList.item(0); 
    return nValue.getNodeValue(); 

Y la salida es ahora

name : Leo 
email : ******@*****.com 
food :   
food : null 
food :   
food : null 
food : 

Lo cual me confunde bastante. ¿Podría decirme dónde estoy equivocado? La cantidad de etiquetas de alimentos no está predefinida.

+0

¿Puedes verificar 'foodNode.getNodeType()' en tu loop? –

+0

NodeList foodList = userEntryElement.getElementsByTagName ("food-list"). GetChildNodes(); y Node foodNode = foodList.item (i); if (fooNode.getNodeType() == Node.ELEMENT_NODE) ​​{Elemento userEntryElement = (Element) foodNode; foodNode.getNodeValue()} – kosa

+0

@ORMapper Si compruebo 'foodNode.getNodeType == Node.Element_Node' antes en el ciclo for antes de imprimir, obtengo dos resultados nulos – YankeeWhiskey

Respuesta

4
((Node) foodNode.getChildNodes().item(0)).getNodeValue() 

Tenga en cuenta que, como puede ver claramente, lidiar con DOM API en Java es bastante doloroso. ¿Has mirado JDOM o dom4j?

1

para obtener los sub-elementos de un elemento que he creado una clase que reemplazar NodeList:

ElementList as Replacement for NodeList

Tenga en cuenta que el código es de dominio público.

/* 
* The code of this file is in public domain. 
*/ 
package org.xins.common.xml; 

import Java.util.LinkedList; 
import org.w3c.dom.Element; 
import org.w3c.dom.Node; 

import org.xins.common.text.ParseException; 

/** 
* An ElementList is an NodeList with the following improvements: 
* 

    Implements List which make it iterable with for each loop * 
    Only includes the direct child of the element * 
    Only includes the elements * 
    By default includes all direct child elements * 
    Preserves the order of the child elements * 
    Includes a method to get the sub element when unique * 


* 
* @author Anthony Goubard 
* 
* @since XINS 3.0 
*/ 
public class ElementList extends LinkedList { 

    /** 
    * The local name of the parent element. 
    */ 
    private String parentName; 

    /** 
    * The local name of the child elements or * for all elements 
    */ 
    private String childName; 

    /** 
    * Creates a list with all direct child element of the given element. 
    * 
    * @param element 
    * the parent element, cannot be null. 
    */ 
    public ElementList(Element element) { 
     this(element, "*"); 
    } 

    /** 
    * Creates a list with all direct child element with a specific local name of the given element. 
    * 
    * @param element 
    * the parent element, cannot be null. 
    * @param childName 
    * the local name of the direct child elements that should be added to the list, cannot be null. 
    */ 
    public ElementList(Element element, String childName) { 
     parentName = element.getTagName(); 
     this.childName = childName; 
     Node child = element.getFirstChild(); 
     while (child != null) { 
     String newChildName = child.getLocalName(); 
     if (newChildName == null) { 
      newChildName = child.getNodeName(); 
     } 
     if (child.getNodeType() == Node.ELEMENT_NODE && 
       (childName.endsWith("*") || childName.equals(newChildName))) { 
      add((Element) child); 
     } 
     child = child.getNextSibling(); 
     } 
    } 

    /** 
    * Gets the unique child of this list. 
    * 
    * @return 
    * the sub-element of this element list, never null. 
    * 
    * @throws ParseException 
    * if no child with the specified name was found, 
    * or if more than one child with the specified name was found. 
    */ 
    public Element getUniqueChildElement() throws ParseException { 
     if (isEmpty()) { 
     throw new ParseException("No \"" + childName + "\" child found in the \"" + parentName + "\" element."); 
     } else if (size() > 1) { 
     throw new ParseException("More than one \"" + childName + "\" children found in the \"" + parentName + "\" element."); 
     } 
     return get(0); 
    } 

    /** 
    * Gets the first child of this element. 
    * 
    * @return 
    * the sub-element of this element, or null if no element is found. 
    */ 
    public Element getFirstChildElement() { 
     if (isEmpty()) { 
     return null; 
     } 
     return get(0); 
    } 
} 
0

Usted puede crear su propia clase NodeList e implementa Iterable.

public class NodeList<T extends Node> extends JavaScriptObject implements Iterable<T> { 

    protected NodeList() { 
    } 

    public final native T getItem(int index) /*-{ 
    return this[index]; 
    }-*/; 

    public final native int getLength() /*-{ 
    return this.length; 
    }-*/; 

    @Override 
    final public Iterator<T> iterator() { 
    return new NodeIterator<T>(this); 
    } 
} 

public class NodeIterator<T extends Node> implements Iterator<T> { 
    private int cursor = 0; 
    private NodeList<T> nodeList; 

    public NodeIterator(NodeList<T> nodeList) { 
    this.nodeList = nodeList; 
    } 

    @Override 
    public boolean hasNext() { 
    return cursor < nodeList.getLength(); 
    } 

    @Override 
    public T next() { 
    if (hasNext()) { 
     return nodeList.getItem(cursor++); 
    } 
    throw new NoSuchElementException(); 
    } 

    @Override 
    public void remove() { 
    throw new UnsupportedOperationException(); 
    } 
} 

NOTA: NodeIterator tiene que estar en archivo separado.

Cuestiones relacionadas