2010-11-13 19 views
16

En Java, mirando a la interfaz NamedNodeMap, ¿cómo se itera con genéricos? Parece que el uso de nodos en lugar de cuerdas, pero no estoy tan seguro de cómo utilizar objetos Node ...iteración foreach genérica de NamedNodeMap

NamedNodeMap namedNodeMap = doc.getAttributes(); 
Map<String, String> stringMap = (Map<String, String>) namedNodeMap; 
for (Map.Entry<String, String> entry : stringMap.entrySet()) { 
    //key,value stuff here 
} 

Sí, puedo ver la forma de repetición sin el uso de medicamentos genéricos y con un habitual para el lazo, pero Me gustaría usar el idioma de arriba? para mapas Por supuesto, el problema parece ser que, a pesar del nombre, NamedNodeMap en realidad no implementa la interfaz de Mapa. :(

supongo que sólo tengo que morder la bala aquí y hacer algo como:?.

/* 
* Iterates through the node attribute map, else we need to specify specific 
* attribute values to pull and they could be of an unknown type 
*/ 
private void iterate(NamedNodeMap attributesList) { 
    for (int j = 0; j < attributesList.getLength(); j++) { 
     System.out.println("Attribute: " 
       + attributesList.item(j).getNodeName() + " = " 
       + attributesList.item(j).getNodeValue()); 
    } 
} 

no hay nada más agradable

+1

No es eso bastante bien? ¡Quiero decir que es un bucle sobre cada nodo de atributo! – dacwe

Respuesta

6

No creo que hay una manera más agradable el uso de las API

Tenga en cuenta que las API W3C DOM Java se especificaron antes de que Java tuviera genéricos o la nueva sintaxis for, o incluso la interfaz Iterator. También tenga en cuenta que las API W3C DOM para Java son en realidad el resultado del mapeo de una IDL ción a Java.

Si desea API más bonitas para manipular XML, etc. en la memoria, tal vez debería consultar JDOM.

6

Puede crear su propia envoltura Iterable para NamedNodeMap y luego usarla en un foreach loop.

Por ejemplo, esto podría ser una aplicación sencilla:

public final class NamedNodeMapIterable implements Iterable<Node> { 

    private final NamedNodeMap namedNodeMap; 

    private NamedNodeMapIterable(NamedNodeMap namedNodeMap) { 
     this.namedNodeMap = namedNodeMap; 
    } 

    public static NamedNodeMapIterable of(NamedNodeMap namedNodeMap) { 
     return new NamedNodeMapIterable(namedNodeMap); 
    } 

    private class NamedNodeMapIterator implements Iterator<Node> { 

     private int nextIndex = 0; 

     @Override 
     public boolean hasNext() { 
      return (namedNodeMap.getLength() > nextIndex); 
     } 
     @Override 
     public Node next() { 
      Node item = namedNodeMap.item(nextIndex); 
      nextIndex = nextIndex + 1; 
      return item; 
     } 

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

    } 

    @Override 
    public Iterator<Node> iterator() { 
     return new NamedNodeMapIterator(); 
    } 
} 

En este caso, este sería el uso:

private void iterate(NamedNodeMap attributesList) { 
    for (Node node : NamedNodeMapIterable.of(attributesList)) { 
     System.out.println("Attribute: " 
       + node.getNodeName() + " = " + node.getNodeValue()); 
    } 
} 

Con un enfoque similar podría crear un Iterable más Map.Entry<String, String> casos .

+0

Este (y su hermano 'NodeListIterable') es un salvavidas absoluto cuando tienes que trabajar con DOM. – biziclop

3

Como no se puede echar a un NamedNodeMapMap, propongo al bucle que utiliza un clásico para el bucle de esa manera:

int numAttrs = namedNodeMap.getLength(); 
System.out.println("Attributes:"); 
for (int i = 0; i < numAttrs; i++){ 
    Attr attr = (Attr) pParameterNode.getAttributes().item(i); 
    String attrName = attr.getNodeName(); 
    String attrValue = attr.getNodeValue(); 
    System.out.println("\t[" + attrName + "]=" + attrValue); 
} 
Cuestiones relacionadas