2010-08-23 16 views
6

me genera un archivo XML como esto:cómo añadir/insertar nodo condicional en XML utilizando LINQ to XML

XElement employees = 
     new XElement("Work", 
      new XElement("record", 
       new XElement("Name", textBox1.Text), 
       new XElement("Phone", "206-555-0144"), 
       new XElement("Address", 
        new XElement("Street1", "123 Main St"), 
        new XElement("City", "Mercer Island"), 
        new XElement("State", "WA"), 
        new XElement("Postal", "68042") 
      )), 
      new XElement("record", 
       new XElement("Name", "22222"), 
       new XElement("Phone", "353245345"), 
       new XElement("Address", 
        new XElement("Street1", "sdfain St"), 
        new XElement("City", "asdf Island"), 
        new XElement("State", "QLD"), 
        new XElement("Postal", "54322") 
      )), 
       new XElement("record", 
       new XElement("Name", "Peter"), 
       new XElement("Phone", "1234"), 
       new XElement("Address", 
        new XElement("Street1", "sd St"), 
        new XElement("City", "cbr"), 
        new XElement("State", "act"), 
        new XElement("Postal", "2600") 
      ) 
     ) 
    ); 

Posteriormente deseo añadir nuevo nodo secundario bajo el nodo "registro" de los padres sobre la base de una condición (donde name = "peter"), algo como esto:

empFile.Elements().Where(r => (string)r.Element("Name") == "Peter") 
        .Add(new XElement("record", 
          new XElement("Mobile", "3253425"), 
          new XElement("Work", 999999) 
         )); 

¿Cómo puedo lograr esto?

+0

nitpick: En lugar de '(cadena) r.Element ("Nombre")', yo sugeriría que el uso de 'r.Element ("Nombre") valor' puede ser mejor forma.. – Timwi

+2

@Timwi: No lo haría. La ventaja de lanzar a cadena es que devuelve nulo en lugar de explotar cuando se lanza desde nulo. Por lo tanto, cualquier elemento sin un subelemento llamado Nombre simplemente se ignora, en lugar de hacer que el programa falle. Casi siempre prefiero usar las conversiones explícitas en LINQ a XML, a menos que la falla en encontrar un elemento/atributo se considere lo suficientemente grave como para justificar una excepción. –

+0

@Jon Skeet: Punto justo. Admito que no pensé en null, pero incluso si lo hiciera, no es obvio que 'op_Explicit' lo acepte y no lo arroje. Tampoco es obvio qué hace 'op_Explicit' si, por ejemplo, el elemento tiene subelementos, mientras que la documentación para la propiedad' Value' es más explícita (jaja, la ironía) al respecto. – Timwi

Respuesta

2

Estás cerca de allí, la cláusula WHERE devuelve un IEnumerable<XElement> ni un solo XElement, por lo que sólo tiene que arreglar eso, es decir, llamar La sola() o .First(), etc

por ejemplo:

XElement xe = empFile.Elements().Where(r => (string)r.Element("Name") == "Peter").Single(); 

xe.Add(new XElement("record", new XElement("Mobile", "3253425"), new XElement("Work", 999999)); 
+0

has asignado el archivo Empfile. elementos(). blahblah a xe y xe.add elementos nuevos, pero encontré que el archivo empFile también se ha actualizado, ¿por qué? – Kiddo

3

Además de la sugerencia de Tim de usar Where seguido de Single o First, vale la pena saber que hay sobrecargas de los métodos que ya tienen predicados. Por ejemplo:

empFile.Elements() 
     .Single(r => (string) r.Element("Name") == "Peter") 
     .Add(...);