Nasıl C # XML oluşturmak?


438

Nasıl C # geçerli XML oluşturabilirim?

Yanıtlar:


510

Bu senaryoya bağlıdır. XmlSerializerkesinlikle bir yoludur ve doğrudan bir nesne modeliyle eşleme avantajına sahiptir. .NET 3.5, XDocumentvb. De çok cana yakın. Boyut çok büyükse, XmlWriterarkadaşın.

Bir XDocumentörnek için:

Console.WriteLine(
    new XElement("Foo",
        new XAttribute("Bar", "some & value"),
        new XElement("Nested", "data")));

Veya aşağıdakilerle aynı XmlDocument:

XmlDocument doc = new XmlDocument();
XmlElement el = (XmlElement)doc.AppendChild(doc.CreateElement("Foo"));
el.SetAttribute("Bar", "some & value");
el.AppendChild(doc.CreateElement("Nested")).InnerText = "data";
Console.WriteLine(doc.OuterXml);

Büyük bir veri akışı yazıyorsanız , DOM yaklaşımlarından herhangi biri ( XmlDocument/ XDocument, vb.) Hızla çok fazla bellek alır. Eğer bir 100 MB XML dosyası yazıyoruz Yani CSV , aşağıdakileri düşünebilirsiniz XmlWriter; bu daha ilkeldir (bir kez yazılan bir yangın hortumu), ancak çok verimlidir (burada büyük bir döngü hayal edin):

XmlWriter writer = XmlWriter.Create(Console.Out);
writer.WriteStartElement("Foo");
writer.WriteAttributeString("Bar", "Some & value");
writer.WriteElementString("Nested", "data");
writer.WriteEndElement();

Son olarak, üzerinden XmlSerializer:

[Serializable]
public class Foo
{
    [XmlAttribute]
    public string Bar { get; set; }
    public string Nested { get; set; }
}
...
Foo foo = new Foo
{
    Bar = "some & value",
    Nested = "data"
};
new XmlSerializer(typeof(Foo)).Serialize(Console.Out, foo);

Bu, sınıflara vb. Eşleme için güzel bir modeldir .; ancak, basit bir şey yapıyorsanız (veya istenen XML gerçekten nesne modeli ile doğrudan bir korelasyona sahip değilse) aşırıya kaçabilir. Başka bir sorun, XmlSerializerdeğişmez türleri serileştirmekten hoşlanmamasıdır: her şeyin bir kamu alıcısı ve belirleyicisi olmalıdır (uygulayarak hepsini kendiniz yapmazsanız IXmlSerializable, bu durumda kullanarak çok fazla kazanmadınız XmlSerializer).


10
XStreamingElement'i unutmayın, msdn.microsoft.com/en-us/library/… . :)
Todd White

1
XmlWriter örneğinde, düzgün çalışması için sondaki yazarı kapatmanız gerektiğini unutmayın - writer.Close (), writer.WriteEndElement () öğesinden sonra gereklidir.
Marko

@Marko'nun söylediği doğru: Yazarı düzgün bir şekilde kapatmak önemlidir. Bunu yapmanın başka bir yolu da, doğrudan writer.Close () öğesini çağırmak yerine. Create () çağrısını şunun gibi bir ifade kullanarak sarabilirsiniz: using (XmlWriter writer = XmlWriter.Create (Console.Out)) {writer.WriteStartElement ("Foo"); vs} Burada başka bir (biraz daha gelişmiş) XmlWriter örneği var: dotnetperls.com/xmlwriter
Morten

@Morten XmlWriter IDisposable'ı uygularsa, deyimi kullanmak en iyi seçenektir.
Marko

İyi eski XMLDocument hepsi var. XML belgesi oluşturuyorsanız, düz, basit ve net.
FrenkyB

60

Denediğim en iyi şey LINQ'dan XSD'ye (çoğu geliştirici tarafından bilinmeyen). Bir XSD Şeması verirsiniz ve arka planda sizin için mükemmel bir şekilde eşleştirilmiş, tam olarak güçlü bir şekilde yazılan nesne modeli (LINQ to XML tabanlı) oluşturur, bu da çalışmak çok kolaydır - ve nesne modelinizi ve XML'nizi günceller ve doğrular. gerçek zaman. Hala "Önizleme" olsa da, onunla herhangi bir hata karşılaşmadım.

Şuna benzeyen bir XSD Şemanız varsa:

  <xs:element name="RootElement">
     <xs:complexType>
      <xs:sequence>
        <xs:element name="Element1" type="xs:string" />
        <xs:element name="Element2" type="xs:string" />
      </xs:sequence>
       <xs:attribute name="Attribute1" type="xs:integer" use="optional" />
       <xs:attribute name="Attribute2" type="xs:boolean" use="required" />
     </xs:complexType>
  </xs:element>

Daha sonra böyle XML oluşturabilirsiniz:

RootElement rootElement = new RootElement;
rootElement.Element1 = "Element1";
rootElement.Element2 = "Element2";
rootElement.Attribute1 = 5;
rootElement.Attribute2 = true;

Veya aşağıdaki gibi bir dosyadan XML yükleyin:

RootElement rootElement = RootElement.Load(filePath);

Veya şu şekilde kaydedin:

rootElement.Save(string);
rootElement.Save(textWriter);
rootElement.Save(xmlWriter);

rootElement.Untyped ayrıca elementi bir XElement formunda verir (LINQ'dan XML'e).


Bu kod çalışma kodu değil gibi görünüyor. böyle yapmak için RootElement
rty zaman

24
new XElement("Foo",
       from s in nameValuePairList
       select
             new XElement("Bar",
                  new XAttribute("SomeAttr", "SomeAttrValue"),
                          new XElement("Name", s.Name),
                          new XElement("Value", s.Value)
                         )
            );

10

XmlWriter iyi XML yazmanın en hızlı yoludur. XDocument, XMLDocument ve diğerleri de iyi çalışır, ancak XML yazmak için optimize edilmez. XML'i olabildiğince hızlı yazmak istiyorsanız, kesinlikle XmlWriter kullanmalısınız.


6
Yani, bilgisayarın XML'i olabildiğince hızlı yazmasını istiyorsanız . Geliştirici, XML'i en kolay ve en doğal şekilde oluşturmak istiyorsanız, XmlWriter muhtemelen çözüm değildir!
sjy


4

Bu kaynak ılımlı bir XML kaydetme / yükleme için yeterli olduğunu düşünüyorum: C # kullanarak XML okuma / yazma .

Görevim müzik notalarını saklamaktı. XML seçiyorum çünkü sanırım .NET görev için kolay çözüm sağlayacak kadar olgunlaştı. Haklıydım :)

Bu benim şarkı dosyası prototipim:

<music judul="Kupu-Kupu yang Lucu" pengarang="Ibu Sud" tempo="120" birama="4/4" nadadasar="1=F" biramapembilang="4" biramapenyebut="4">
    <not angka="1" oktaf="0" naikturun="" nilai="1"/>
    <not angka="2" oktaf="0" naikturun="" nilai="0.5"/>
    <not angka="5" oktaf="1" naikturun="/" nilai="0.25"/>
    <not angka="2" oktaf="0" naikturun="\" nilai="0.125"/>
    <not angka="1" oktaf="0" naikturun="" nilai="0.0625"/>
</music>

Bu oldukça kolay bir şekilde çözülebilir:

Dosyaya Kaydet için:

 private void saveToolStripMenuItem_Click(object sender, EventArgs e)
 {
     saveFileDialog1.Title = "Save Song File";
     saveFileDialog1.Filter = "Song Files|*.xsong";
     if (saveFileDialog1.ShowDialog() == DialogResult.OK)
     {
         FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.Create);
         XmlTextWriter w = new XmlTextWriter(fs, Encoding.UTF8);
         w.WriteStartDocument();
         w.WriteStartElement("music");
         w.WriteAttributeString("judul", Program.music.getTitle());
         w.WriteAttributeString("pengarang", Program.music.getAuthor());
         w.WriteAttributeString("tempo", Program.music.getTempo()+"");
         w.WriteAttributeString("birama", Program.music.getBirama());
         w.WriteAttributeString("nadadasar", Program.music.getNadaDasar());
         w.WriteAttributeString("biramapembilang", Program.music.getBiramaPembilang()+"");
         w.WriteAttributeString("biramapenyebut", Program.music.getBiramaPenyebut()+"");

         for (int i = 0; i < listNotasi.Count; i++)
         {
             CNot not = listNotasi[i];
             w.WriteStartElement("not");
             w.WriteAttributeString("angka", not.getNot() + "");
             w.WriteAttributeString("oktaf", not.getOktaf() + "");
             String naikturun="";
             if(not.isTurunSetengah())naikturun="\\";
             else if(not.isNaikSetengah())naikturun="/";
             w.WriteAttributeString("naikturun",naikturun);
             w.WriteAttributeString("nilai", not.getNilaiNot()+"");
             w.WriteEndElement();
         }
         w.WriteEndElement();

         w.Flush();
         fs.Close();
     }

 }

Yükleme dosyası için:

openFileDialog1.Title = "Open Song File";
openFileDialog1.Filter = "Song Files|*.xsong";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
    FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open);
    XmlTextReader r = new XmlTextReader(fs);

    while (r.Read())
    {
        if (r.NodeType == XmlNodeType.Element)
        {
            if (r.Name.ToLower().Equals("music"))
            {
                Program.music = new CMusic(r.GetAttribute("judul"),
                    r.GetAttribute("pengarang"),
                    r.GetAttribute("birama"),
                    Convert.ToInt32(r.GetAttribute("tempo")),
                    r.GetAttribute("nadadasar"),
                    Convert.ToInt32(r.GetAttribute("biramapembilang")),
                    Convert.ToInt32(r.GetAttribute("biramapenyebut")));
            }
            else
                if (r.Name.ToLower().Equals("not"))
                {
                    CNot not = new CNot(Convert.ToInt32(r.GetAttribute("angka")), Convert.ToInt32(r.GetAttribute("oktaf")));
                    if (r.GetAttribute("naikturun").Equals("/"))
                    {
                        not.setNaikSetengah();
                    }
                    else if (r.GetAttribute("naikturun").Equals("\\"))
                    {
                        not.setTurunSetengah();
                    }
                    not.setNilaiNot(Convert.ToSingle(r.GetAttribute("nilai")));
                    listNotasi.Add(not);
                }
        }
        else
            if (r.NodeType == XmlNodeType.Text)
            {
                Console.WriteLine("\tVALUE: " + r.Value);
            }
    }
}

}
}

1

Basit şeyler için, sadece System.XML'de bulunan XmlDocument / XmlNode / XmlAttribute sınıflarını ve XmlDocument DOM kullanıyorum.

Benim için XML üretir, sadece birkaç öğeyi birbirine bağlamam gerekiyor.

Ancak, daha büyük şeylerde XML serileştirme kullanıyorum.


1

Basit durumlar için, XmlOutput'a bakmayı da öneririm Xml oluşturmak için akıcı bir arayüze .

XmlOutput, geçerli Xml oluştururken okunabilir ve bakımı kolay kodla basit Xml oluşturmak için mükemmeldir. Orjinal sonrası bazı büyük örnekler vardır.


-3

Yukarıdaki gibi.

Stringbuilder.append () kullanıyorum.

Çok basit ve daha sonra xmldocument.load (parametre olarak strinbuilder nesnesi) yapabilirsiniz.

Muhtemelen append parametresinde string.concat kullanarak kendinizi bulacaksınız, ancak bu çok basit bir yaklaşımdır.


11
Bir şeyi düzgün bir şekilde kodlamayı ve yasadışı Xml yazmayı unutmanız hariç.
Robert Paulson

3
Bu cevap kesinlikle çarptı, ancak bu soruya dayanarak XML oluşturduğum kendi uygulamalardan birine baktım. Benim özel projem için sürekli olarak StringBuilder üzerinden bina XDocument / XmlWriter kullanmaktan% 10 daha hızlı işlem süreleri ile sonuçlandı bulundu. Ama XML ile rahat hissediyorum ve bu benim özel projem için. (Referans olarak, son XML boyutları yaklaşık 8.000 satırdan fazla 3.4 MB'dir.)
James Skemp

2
Eğer uygulama performansı (? Burada milisaniye iyileştirmeler söz ediyoruz) ve uygulama bakımı arasındaki değiş tokuşu ölçülen eğer merak olurdu (sizin mühendisler şimdi değişiklik yapmadan önce bir saat kodu ile kendilerini tanıtmak gerekir?)
Dan Esparza
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.