Tworzenie plików XML przy użyciu XDocument w C #

84

Mam List<string>„sampleList”, który zawiera

Data1
Data2
Data3...

Struktura pliku jest podobna do

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

Obecnie używam XmlDocument, aby to zrobić.

Przykład:

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");

Jak mogę utworzyć taką samą strukturę XML za pomocą XDocument?

Thorin Oakenshield
źródło
8
Wyślij kod, który do tej pory napisałeś. Ludzie na ogół nie lubią pisać kodu za Ciebie.
Mitch Wheat
5
Zgoda - w rzeczywistości jest to niezwykle proste w jednym oświadczeniu, ale samo udzielenie odpowiedzi nie pomoże ci się wiele nauczyć.
Jon Skeet

Odpowiedzi:

191

Dzięki LINQ to XML jest to znacznie prostsze dzięki trzem funkcjom:

  • Możesz skonstruować obiekt bez znajomości dokumentu, którego jest częścią
  • Możesz skonstruować obiekt i podać dzieci jako argumenty
  • Jeśli argument jest iterowalny, będzie iterowany

Tutaj możesz po prostu zrobić:

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");
}

Celowo użyłem tego układu kodu, aby sam kod odzwierciedlał strukturę dokumentu.

Jeśli potrzebujesz elementu zawierającego węzeł tekstowy, możesz go skonstruować, przekazując tekst jako kolejny argument konstruktora:

// Constructs <element>text within element</element>
XElement element = new XElement("element", "text within element");
Jon Skeet
źródło
16
Uwaga: jeśli masz elementy, które muszą mieć „tekst wewnętrzny”, dodajesz je w następujący sposób: new XElement("description","this is the inner text of the description element.");(podobnie jak w przypadku dodawania par atrybut / wartość)
tajemnica
Bardzo fajne podejście. Przez chwilę zastanawiałem się, jak jednocześnie dodać atrybuty i linq-wyrażenie elementów. Więc jeśli ktoś jest zainteresowany, wybieram: new XElement("info", new object[] { new XAttribute("foo", "great"), new XAttribute("bar", "not so great") }.Concat(list.Select(x => new XElement("child", ...))))Z odpowiednimi zawinięciami linii wygląda to całkiem dobrze.
Sebastian Werk
0

Użycie metody .Save oznacza, że ​​dane wyjściowe będą miały BOM, z czego nie wszystkie aplikacje będą zadowolone. Jeśli nie chcesz BOM-a, a nie jesteś pewien, radzę tego nie robić, prześlij XDocument przez pisarza:

using (var writer = new XmlTextWriter(".\\your.xml", new UTF8Encoding(false)))
{
    doc.Save(writer);
}
gościnny użytkownik
źródło