web-dev-qa-db-fra.com

Comment puis-je générer du XML en C #?

Comment générer un code XML valide en C #?

428
Dan Esparza

Cela dépend du scénario. XmlSerializer est certainement une solution et présente l'avantage de pouvoir être directement mappé sur un modèle d'objet. Dans .NET 3.5, XDocument, etc. sont également très sympathiques. Si la taille est très grande, alors XmlWriter est votre ami.

Pour un exemple XDocument:

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

Ou la même chose avec 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);

Si vous écrivez un flux de données large, toutes les approches DOM (telles que XmlDocument/XDocument, etc.) utiliseront rapidement beaucoup de mémoire. Donc, si vous écrivez un fichier XML de 100 Mo à partir de CSV , vous pourriez envisager de XmlWriter; c'est plus primitif (un firehose à écriture unique), mais très efficace (imaginez une grande boucle ici):

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

Enfin, via 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);

Ceci est un modèle de Nice pour la mise en correspondance avec des classes, etc. Cependant, cela peut être excessif si vous faites quelque chose de simple (ou si le XML souhaité n'a pas vraiment de corrélation directe avec le modèle d'objet). Un autre problème avec XmlSerializer est qu'il n'aime pas sérialiser les types immuables: tout doit avoir un getter public et (sauf si vous le faites vous-même en implémentant IXmlSerializable, auquel cas vous n'avez pas beaucoup gagné en utilisant XmlSerializer).

498
Marc Gravell

La meilleure chose que j'ai essayée est LINQ to XSD (inconnu de la plupart des développeurs). Vous lui donnez un schéma XSD et génère un modèle d'objet fortement typé complet (basé sur LINQ to XML) parfaitement mappé, ce qui est très facile à utiliser - et met à jour et valide votre modèle d'objet et XML dans temps réel. Bien que ce soit encore "Aperçu", je n’ai rencontré aucun bogue.

Si vous avez un schéma XSD qui ressemble à ceci:

  <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>

Ensuite, vous pouvez simplement construire du XML comme ceci:

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

Ou simplement charger un fichier XML à partir d'un fichier comme ceci:

RootElement rootElement = RootElement.Load(filePath);

Ou enregistrez-le comme ceci:

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

rootElement.Untyped renvoie également l'élément sous la forme d'un XElement (de LINQ à XML).

59
user65199
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)
                         )
            );
23
Vincent

Je voudrais donner XLINQ (lire: LINQ to XML) un essai. C'est facile, intuitif et facilement modifiable.

Exemple: Lecture et écriture de XML avec XLinq

21
Chad Moran

XmlWriter est le moyen le plus rapide d’écrire du bon XML. XDocument, XMLDocument et quelques autres fonctionnent également, mais ne sont pas optimisés pour l'écriture XML. Si vous voulez écrire le XML aussi vite que possible, vous devez absolument utiliser XmlWriter.

9

Consultez également XmlDocument fluent interface de Mark S. Rasmussen, qui fournit une sortie XML facile à saisir/à lire.

9
Rob Walker

Je pense que cette ressource devrait suffire pour une sauvegarde/chargement XML modéré: Lecture/écriture XML en utilisant C # .

Ma tâche était de stocker la notation musicale. Je choisis XML, parce que je suppose que . NET a suffisamment mûri pour permettre une solution aisée à la tâche. J'avais raison :)

Ceci est mon prototype de fichier de chanson:

<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>

Cela peut être résolu assez facilement:

Pour enregistrer dans un fichier:

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

 }

Pour charger le fichier:

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

}
}
3
swdev

Dans le passé, j'avais créé mon schéma XML, puis utilisé un outil pour générer des classes C # qui se sérialiseraient sur ce schéma. L'outil de définition de schéma XML en est un exemple.

http://msdn.Microsoft.com/en-us/library/x6c1kb0s (VS.71) .aspx

3
Bob

Pour des choses simples, j'utilise simplement les classes XmlDocument/XmlNode/XmlAttribute et le DOM XmlDocument trouvé dans System.XML.

Il génère le XML pour moi, il me suffit de relier quelques éléments.

Cependant, sur de plus grandes choses, j'utilise la sérialisation XML.

1
FlySwat

Pour des cas simples, je suggérerais également de regarder XmlOutput une interface fluide pour la construction de XML.

XmlOutput est idéal pour la création XML simple avec un code lisible et maintenable, tout en générant du code XML valide. Le post original a de très bons exemples.

1
Todd