2010-11-13 12 views
16

In Java, guardando l'interfaccia NamedNodeMap, come si esegue l'iterazione con i generici? Sembra di usare Nodo piuttosto che String, ma io non sono così sicuro come utilizzare gli oggetti Nodo ...foreach iterazione generica di 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ì, posso vedere come iterare senza l'utilizzo di farmaci generici e con un regolare ciclo for, ma Mi piacerebbe usare l'idioma sopra? per le mappe. Ovviamente, il problema sembra essere che, nonostante il nome, NamedNodeMap non implementa effettivamente l'interfaccia Mappa! :(

Immagino che devo solo morso il proiettile qui e fare qualcosa di simile:?.

/* 
* 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()); 
    } 
} 

non c'è niente di più bello

+1

Non è che molto bello? Voglio dire che è un ciclo su ciascun nodo di attributo! – dacwe

risposta

6

Non credo ci sia un modo migliore utilizzando tali API

Tenere presente che le API Java del DOM W3C sono state specificate prima che Java avesse generici o la nuova sintassi for o anche l'interfaccia Iterator. Si tenga anche presente che le API DOM W3C per Java sono effettivamente il risultato del mapping di una specifica IDL zione a Java.

Se vuoi API più belle per manipolare XML, ecc. In memoria, forse dovresti dare un'occhiata a JDOM.

6

È possibile creare il proprio wrapper Iterable per NamedNodeMap e quindi utilizzarlo in un ciclo foreach.

Per esempio, questo potrebbe essere una semplice implementazione:

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

In questo caso, questo sarebbe l'utilizzo:

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

Con un approccio simile è possibile creare un Iterable oltre Map.Entry<String, String> casi .

+0

Questo (e suo fratello 'NodeListIterable') è un assoluto salvataggi quando devi lavorare con DOM. – biziclop

3

Come non puoi lanciare NamedNodeMap ad un Map, suggerisco a ciclo utilizzando un classico ciclo di simile:

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); 
} 
Problemi correlati