2009-10-29 19 views
5

Tengo un XDocument y tengo que eliminar un nodo y volver a agregar el mismo nodo después de alguna manipulación (mi nodo xelement es complejo y tiene nodos internos como bien). ¿Alguien ha conseguido una buena manera de hacerlo ya que mi nuevo nodo manipulado se agrega al final del xmldocument? Cualquier fragmento de código sería muy apreciado.Linq a XML: elimine un nodo y agregue un nuevo nodo en el mismo lugar

Respuesta

4

Si acaba de editar el nodo, entonces ¿por qué quitarlo del todo? Solo haz una referencia en el árbol y edítalo en el lugar.

Si eso no es una opción, por alguna razón, entonces una forma de hacerlo es la siguiente: una vez que haya encontrado el XElement (o, en general, XNode) es necesario sustituir en el árbol, cree un nuevo XElement para servir como reemplazo, y luego use el método XNode.ReplaceWith en el elemento anterior, pasando uno nuevo como argumento.

8

Si entiendo bien, esto debería ayudarlo a hacerlo.

SolarSystem.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<SolarSystem> 
    <Planets> 
    <Planet Id="1"> 
     <Name>Mercury</Name> 
    </Planet> 
    <Planet Id="2"> 
     <Name>Venus</Name> 
    </Planet> 
    <Planet Id="3"> 
     <Name>Earth</Name> 
    </Planet> 
    </Planets> 
</SolarSystem> 

El código encuentra el <Planet> Mercurio, añade un elemento adicional a ella, lo elimina y vuelve a insertar al final de la colección <Planets>.

XDocument SolarSystem = XDocument.Load(Server.MapPath("SolarSystem.xml")); 
IEnumerable<XElement> Planets = SolarSystem.Element("SolarSystem").Element("Planets").Elements("Planet"); 

// identify and change Mercury 
XElement Mercury = Planets.Where(p => p.Attribute("Id").Value == "1").FirstOrDefault(); 
Mercury.Add(new XElement("YearLengthInDays", "88")); 

// remove Mercury from current position, and add back in at the end 
Mercury.Remove(); 
Planets.Last().AddAfterSelf(Mercury); 

// save it as new file 
SolarSystem.Save(Server.MapPath("NewSolarSystem.xml")); 

lo que da:

<?xml version="1.0" encoding="UTF-8"?> 
    <SolarSystem> 
    <Planets> 
     <Planet Id="2"> 
     <Name>Venus</Name> 
     </Planet> 
     <Planet Id="3"> 
     <Name>Earth</Name> 
     </Planet> 
     <Planet Id="1"> 
     <Name>Mercury</Name> 
     <YearLengthInDays>88</YearLengthInDays> 
     </Planet> 
    </Planets> 
    </SolarSystem> 
+1

+1: Muestra de Nice 101 para que la gente comience –

1

Esto solo se basa en el ejemplo anterior de @Ralph Lavelle. Creé una aplicación de consola completa para poder jugar con el código & y comprenderlo mejor. Pensé que lo compartiría. Utiliza exactamente el mismo XML de muestra de arriba, pero tuve que eliminar las referencias a Server.MapPath() ya que no pude encontrar la manera de hacerlo funcionar. Aquí tienes:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Xml.Linq; 

class LinqDemo 
{ 
static void Main() 
    { 
     XDocument SolarSystem = XDocument.Load("SolarSystem.xml"); 
     IEnumerable<XElement> Planets = SolarSystem.Element("SolarSystem").Element("Planets").Elements("Planet"); 

     // identify and change Mercury 
     XElement Mercury = Planets.Where(p => p.Attribute("Id").Value == "1").FirstOrDefault(); 
     Mercury.Add(new XElement("YearLengthInDays", "88")); 

     // remove Mercury from current position, and add back in at the end 
     Mercury.Remove(); 
     Planets.Last().AddAfterSelf(Mercury); 

     // save it as new file 
     SolarSystem.Save("NewSolarSystem.xml"); 
    } 
} 

Quizás esto ayude a otro novato de LINQ como yo.

+0

Aprecie el ejemplo de trabajo conciso. Se encontró que 'using System;' es *** *** *** requerido. Pero eso 'usando System.Xml;' *** es *** obligatorio. – DavidRR

+0

Eres bienvenido. Odio encontrar una pregunta que parece tener la respuesta que estoy buscando y un código impreciso sobre cómo hacerlo. Buena captura en el error de uso. – delliottg

Cuestiones relacionadas