Creación de archivos XML usando XDocument en C #

83

Tengo una List<string>"sampleList" que contiene

Data1
Data2
Data3...

La estructura del archivo es como

<file>
   <name filename="sample"/>
   <date modified ="  "/>
   <info>
     <data value="Data1"/> 
     <data value="Data2"/>
     <data value="Data3"/>
   </info>
</file>

Actualmente estoy usando XmlDocument para hacer esto.

Ejemplo:

List<string> lst;
XmlDocument XD = new XmlDocument();
XmlElement root = XD.CreateElement("file");
XmlElement nm = XD.CreateElement("name");
nm.SetAttribute("filename", "Sample");
root.AppendChild(nm);
XmlElement date = XD.CreateElement("date");
date.SetAttribute("modified", DateTime.Now.ToString());
root.AppendChild(date);
XmlElement info = XD.CreateElement("info");
for (int i = 0; i < lst.Count; i++) 
{
    XmlElement da = XD.CreateElement("data");
    da.SetAttribute("value",lst[i]);
    info.AppendChild(da);
}
root.AppendChild(info);
XD.AppendChild(root);
XD.Save("Sample.xml");

¿Cómo puedo crear la misma estructura XML usando XDocument?

Thorin Escudo de Roble
fuente
8
Publique el código que ha escrito hasta ahora. A la gente generalmente no le gusta escribir su código por usted.
Mitch Wheat
5
De acuerdo, esto es extremadamente simple de hacer en una sola declaración, pero solo darte la respuesta no te ayudará a aprender mucho.
Jon Skeet

Respuestas:

191

LINQ to XML permite que esto sea mucho más simple, a través de tres características:

  • Puede construir un objeto sin conocer el documento del que forma parte
  • Puede construir un objeto y proporcionar a los niños como argumentos
  • Si un argumento es iterable, se repetirá

Así que aquí puedes hacer:

void Main()
{
    List<string> list = new List<string>
    {
        "Data1", "Data2", "Data3"
    };

    XDocument doc =
      new XDocument(
        new XElement("file",
          new XElement("name", new XAttribute("filename", "sample")),
          new XElement("date", new XAttribute("modified", DateTime.Now)),
          new XElement("info",
            list.Select(x => new XElement("data", new XAttribute("value", x)))
          )
        )
      );

    doc.Save("Sample.xml");
}

He usado este diseño de código deliberadamente para hacer que el código refleje la estructura del documento.

Si desea un elemento que contenga un nodo de texto, puede construirlo simplemente pasando el texto como otro argumento de constructor:

// Constructs <element>text within element</element>
XElement element = new XElement("element", "text within element");
Jon Skeet
fuente
16
Nota: Si tiene elementos que necesitan tener "texto interno", los agrega así: new XElement("description","this is the inner text of the description element.");(similar a cómo agrega pares de atributo / valor)
Myster
Muy buen enfoque. Luché un momento sobre cómo agregar atributos y una expresión de elementos a la vez. Entonces, si alguien está interesado, elijo: new XElement("info", new object[] { new XAttribute("foo", "great"), new XAttribute("bar", "not so great") }.Concat(list.Select(x => new XElement("child", ...))))Con los ajustes de línea apropiados, esto se ve bastante bien nuevamente.
Sebastian Werk
0

El uso del método .Save significa que la salida tendrá una lista de materiales, con la que no todas las aplicaciones estarán satisfechas. Si no desea una lista de materiales, y si no está seguro, le sugiero que no lo haga, entonces pase el XDocument a través de un escritor:

using (var writer = new XmlTextWriter(".\\your.xml", new UTF8Encoding(false)))
{
    doc.Save(writer);
}
usuario invitado
fuente