Comment puis-je générer du XML valide en C #?
Comment puis-je générer du XML valide en C #?
Réponses:
Cela dépend du scénario. XmlSerializer
est certainement un moyen et a l'avantage de correspondre directement à un modèle d'objet. Dans .NET 3.5, XDocument
etc. sont également très conviviaux. Si la taille est très grande, alors XmlWriter
c'est votre ami.
Pour un XDocument
exemple:
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 grand flux de données, l'une des approches DOM (telles que XmlDocument
/ XDocument
, etc.) prendra rapidement beaucoup de mémoire. Donc, si vous écrivez un fichier XML de 100 Mo à partir de CSV , vous pourriez envisager XmlWriter
; c'est plus primitif (un firehose à écriture unique), mais très efficace (imaginez une grosse 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);
C'est un joli modèle pour le mappage aux classes, etc .; cependant, il peut être exagéré 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 XmlSerializer
est qu'il n'aime pas sérialiser les types immuables: tout doit avoir un getter et un setter publics (à moins que vous ne fassiez tout vous-même en implémentant IXmlSerializable
, auquel cas vous n'avez pas beaucoup gagné en utilisant XmlSerializer
).
La meilleure chose que j'ai essayé de loin est LINQ to XSD (qui est inconnu de la plupart des développeurs). Vous lui donnez un schéma XSD et il génère un modèle d'objet complet fortement typé parfaitement mappé (basé sur LINQ to XML) pour vous en arrière-plan, ce qui est vraiment facile à travailler - et il met à jour et valide votre modèle d'objet et XML dans temps réel. Bien qu'il soit toujours "Aperçu", je n'ai rencontré aucun bogue avec.
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 créer du XML comme ceci:
RootElement rootElement = new RootElement;
rootElement.Element1 = "Element1";
rootElement.Element2 = "Element2";
rootElement.Attribute1 = 5;
rootElement.Attribute2 = true;
Ou chargez simplement un XML à partir d'un fichier comme celui-ci:
RootElement rootElement = RootElement.Load(filePath);
Ou enregistrez-le comme ceci:
rootElement.Save(string);
rootElement.Save(textWriter);
rootElement.Save(xmlWriter);
rootElement.Untyped
donne également l'élément sous la forme d'un XElement (de LINQ à XML).
RootElement
XmlWriter est le moyen le plus rapide d'écrire du bon XML. XDocument, XMLDocument et quelques autres fonctionnent également bien, mais ne sont pas optimisés pour l'écriture XML. Si vous souhaitez écrire le XML le plus rapidement possible, vous devez absolument utiliser XmlWriter.
Dans le passé, j'ai créé mon schéma XML, puis utilisé un outil pour générer des classes C # qui seront sérialisées 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
Je pense que cette ressource devrait suffire pour une sauvegarde / charge XML modérée: lecture / écriture XML en utilisant C # .
Ma tâche était de stocker la notation musicale. Je choisis XML, car je suppose que .NET a suffisamment mûri pour permettre une solution facile pour la tâche. J'avais raison :)
Voici 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);
}
}
}
}
}
Pour des choses simples, j'utilise simplement les classes XmlDocument / XmlNode / XmlAttribute et XmlDocument DOM trouvés dans System.XML.
Il génère le XML pour moi, j'ai juste besoin de lier quelques éléments ensemble.
Cependant, sur des choses plus importantes, j'utilise la sérialisation XML.
Pour les cas simples, je suggère également de regarder XmlOutput une interface fluide pour construire Xml.
XmlOutput est idéal pour la création de Xml simple avec du code lisible et maintenable, tout en générant du Xml valide. Le post original a de bons exemples.
Comme ci-dessus.
J'utilise stringbuilder.append ().
Très simple, et vous pouvez ensuite faire xmldocument.load (objet strinbuilder comme paramètre).
Vous vous retrouverez probablement à utiliser string.concat dans le paramètre append, mais c'est une approche très simple.