2009-05-17 5 views
26

Ho bisogno di rimuovere un XmlNode in base a una condizione. Come farlo?Come rimuovere un XmlNode da XmlNodeList

foreach (XmlNode drawNode in nodeList) 
{ 
     //Based on a condition 
     drawNode.RemoveAll(); //need to remove the entire node      

} 
+0

Qual è il problema? –

risposta

4

Non è possibile utilizzare facilmente gli iteratori (istruzione foreach) per eliminare i nodi. Come si vede, è possibile effettuare le seguenti operazioni:

1) Nel proprio ciclo foreach, salvare un elenco di tutti gli elementi che devono essere rimossi. Quindi fai scorrere solo quegli elementi e rimuovili.

2) Utilizzare un ciclo normale e tenere traccia del quale è l'elemento successivo da visitare dopo aver eliminato un elemento.

Modifica: quando si utilizza un ciclo for farlo come suggerisce Fredrik, eseguendo il ciclo all'indietro.

+1

Upvoting per la prima risposta; la parte 2 suona un po 'complicata nel modo in cui la descrivi, di solito è più facile scorrere l'elenco in ordine inverso, quindi non devi preoccuparti del prossimo indice. – overslacked

+0

Perché ho aggiunto "..mangiare la traccia di quale è l'elemento successivo da visitare ..." era perché non sapevo in che modo il ciclo for sarebbe stato implementato, se i nodi sono nell'ordine corretto ecc. –

4

Se si sta tentando di rimuovere un nodo dal DOM XML, questo non è il modo corretto. Perché uno XMLNodeList è solo un elenco di nodi. Piuttosto si desidera rimuovere il nodo dal nodo genitore. Come questo:

XmlNode parentNode = // some value 
XmlNode drawNode = // some value 
parentNode.ParentNode.RemoveChild(drawNode); 
+1

AFIK , XmlNode "RemoveNode" non esiste in C#. –

+1

Effettivamente, almeno a 4.0. Penso che intendesse: drawNode.ParentNode.RemoveChild (drawNode); È un po 'brutto ma fa quello che mi aspetterei che una funzione "rimuovi" faccia: zappa il drawNode e qualsiasi cosa in esso contenuta. – philw

+0

@philw - Credo che tu abbia ragione. Ho modificato la risposta di conseguenza –

57

Questo dovrebbe fare il trucco per voi:

for (int i = nodeList.Count - 1; i >= 0; i--) 
{ 
    nodeList[i].ParentNode.RemoveChild(nodeList[i]); 
} 

Se si esegue un ciclo utilizzando un normale ciclo for, e anello su di esso "a ritroso", è possibile rimuovere gli elementi, come si va.

Aggiornamento: ecco un esempio completo, incluso il caricamento di un file XML, individuando i nodi, eliminarli e salvare il file:

XmlDocument doc = new XmlDocument(); 
doc.Load(fileName); 
XmlNodeList nodes = doc.SelectNodes("some-xpath-query"); 
for (int i = nodes.Count - 1; i >= 0; i--) 
{ 
    nodes[i].ParentNode.RemoveChild(nodes[i]); 
} 
doc.Save(fileName); 
+0

Non dovrebbe funzionare anche se collegato in avanti ?? – devnull

+1

In questo caso particolare, funzionerebbe poiché il codice non rimuove i nodi dalla raccolta XmlNodeList, ma dal DOM XmlDocument, ma in molti altri casi l'eliminazione di elementi in un ciclo continuo in avanti può dare risultati imprevisti (come gli elementi che non sono rimosso). Movimento riflesso, suppongo; o) –

+0

Questo è il metodo iterativo ampiamente utilizzato per rimuovere l'elemento da collections.thanks fredrik per l'illuminazione del codice saggio a tutti :) – Ravisha

1

non è il seguito di un po 'più semplice:

XmlDocument doc = new XmlDocument(); 
doc.Load(fileName); 
XmlNodeList nodes = doc.SelectNodes("some-xpath-query"); 
while (nodes.FirstChild != null) {  
    nodes.RemoveChild(nodes.FirstChild); 
} 
doc.Save(fileName); 
0
XmlNodeList xnodeContact = xmldocContact.GetElementsByTagName("contact"); 
      foreach (ListViewItem item in listViewContacts.Items) 
      { 
       if (item.Checked) 
       { 
        if (item.Index >= 0) 
         xnodeContact[0].ParentNode.RemoveChild(xnodeContact[0]); 
         listViewContacts.Items.Remove(item); 
        } 
       } 
      } 
      xmldocContact.Save(appdataPath + "\\WhatAppcontactList.xml"); 
      Invalidate();