2010-07-09 27 views
8

Esto elimina todos los elementos del documento:nodos Extracción de XDocument

 XDocument document = XDocument.Load(inputFile); 
     foreach (XElement element in document.Elements()) 
     { 
      element.Remove(); 
     } 
     document.Save(outputFile); 

Esto no tiene ningún efecto:

 XDocument document = XDocument.Load(inputFile); 
     foreach (XElement element in document.Elements()) 
     { 
      //element.Remove(); 
      foreach (XElement child in element.Elements()) 
       child.Remove(); 
     } 
     document.Save(outputFile); 

Me estoy perdiendo algo aquí? Dado que todas estas son referencias a elementos dentro del XDocument, ¿no deberían los cambios entrar en vigencia? ¿Hay alguna otra forma en que debería eliminar a los niños anidados de un XDocument?

Gracias!

+0

¿Usted ha depurado el código? ¿Estás seguro de que element.Elements() está devolviendo elementos secundarios? Solo estoy buscando información un poco más sobre exactamente lo que está viendo suceder. – jrista

+0

@jrista Devuelve elementos secundarios, pero el problema parece ser que el enumerador se comporta de manera diferente después de un '.Eliminar()'. – Jake

+1

Sí, eso es lo que esperaría. Los enumeradores generalmente lanzan excepciones cuando modifica la colección, ya que dependen mucho de la estabilidad de la colección subyacente para funcionar correctamente. De hecho, me sorprende que pueda continuar después de eliminar un nodo mientras usa un foreach/enumerator. En general, recomendaría usar un ciclo while (o posiblemente para ... pero eso es más complicado), en lugar de un foreach. – jrista

Respuesta

18

Al parecer, cuando iterar sobre element.Elements(), llamar a un Remove() en una de las causas de los niños el enumerador al yield break. La iteración sobre element.Elements().ToList() resolvió el problema.

+0

¿Es esto específico para XPath entonces? – Neo

+0

@Neo ¿De qué manera? Como [jirsta] (http://stackoverflow.com/users/111554/jrista) señaló anteriormente, la mayoría de los enumeradores se romperán cuando cambie la colección subyacente. – Jake

+0

Sí, soy consciente de que normalmente se produce una excepción InvalidOperationException. Mi pregunta es sobre 'ruptura de rendimiento'. ¿Es esto específico para XPath vis-à-vis @ jrista el comentario silencioso? – Neo

2

He aquí un ejemplo de otra manera usando System.Xml.XPath (cambiar la consulta XPath para satisfacer sus necesidades):

const string xml = 
    @"<xml> 
     <country> 
      <states> 
       <state>arkansas</state> 
       <state>california</state> 
       <state>virginia</state> 
      </states> 
     </country> 
    </xml>"; 
XDocument doc = XDocument.Parse(xml); 
doc.XPathSelectElements("//xml/country/states/state[.='arkansas']").ToList() 
    .ForEach(el => el.Remove());; 
Console.WriteLine(doc.ToString()); 
Console.ReadKey(true); 
2

Al utilizar XDocument prueba este lugar:

XDocument document = XDocument.Load(inputFile); 
foreach (XElement element in document.Elements()) 
{ 
    document.Element("Root").SetElementValue(element , null); 
} 
document.Save(outputFile) 

Saludos, Todd

Cuestiones relacionadas