Como posso construir XML em C#?
Como posso gerar XML válido em C#?
11 answers
XmlSerializer
é certamente uma maneira e tem a vantagem de mapear diretamente para um modelo objeto. In. net 3.5, XDocument
, etc. também são muito amigáveis. Se o tamanho é muito grande, então XmlWriter
é seu amigo.
Para um exemplo XDocument
:
Console.WriteLine(
new XElement("Foo",
new XAttribute("Bar", "some & value"),
new XElement("Nested", "data")));
Ou o mesmo com 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);
Se você está escrevendo um grande fluxo de Dados, Então qualquer um dos DOM se aproxima (tais como XmlDocument
/XDocument
, etc.) irá rapidamente levar uma grande quantidade de memória. Então, se você é escrevendo um arquivo XML de 100 MB de CSV , você pode considerar XmlWriter
; isto é mais primitivo (um dispositivo de gravação-uma vez), mas muito eficiente (imagine um loop grande aqui):
XmlWriter writer = XmlWriter.Create(Console.Out);
writer.WriteStartElement("Foo");
writer.WriteAttributeString("Bar", "Some & value");
writer.WriteElementString("Nested", "data");
writer.WriteEndElement();
Finalmente, 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);
Este é um bom modelo de mapeamento para classes, etc.; no entanto, pode ser exagerado se você está fazendo algo simples (ou se o XML desejado não tem realmente uma correlação direta com o modelo objeto). Outro problema com XmlSerializer
é que ele não gosta de serializar tipos imutáveis: tudo deve ter um getter público e setter (a menos que você mesmo o faça executando IXmlSerializable
, caso em que você não ganhou muito usando XmlSerializer
).
A melhor coisa que já tentei é LINQ para XSD (o que é desconhecido para a maioria dos programadores). Você lhe dá um esquema XSD e ele gera um modelo de objeto perfeitamente mapeado (baseado em LINQ para XML) para você em segundo plano, o que é realmente fácil de trabalhar-e ele atualiza e valida seu modelo de objeto e XML em tempo real. Enquanto ainda é "Preview", eu não encontrei nenhum bugs com ele.
Se tiver um esquema XSD que se pareça com isto:
<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>
Então você pode simplesmente construir XML como este:
RootElement rootElement = new RootElement;
rootElement.Element1 = "Element1";
rootElement.Element2 = "Element2";
rootElement.Attribute1 = 5;
rootElement.Attribute2 = true;
Ou simplesmente carregar um XML de um ficheiro como este:
RootElement rootElement = RootElement.Load(filePath);
Ou guarda-o assim:
rootElement.Save(string);
rootElement.Save(textWriter);
rootElement.Save(xmlWriter);
rootElement.Untyped
também produz o elemento em forma de um XElement (de LINQ para XML).
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)
)
);
Eu daria ao XLINQ (leia: LINQ para XML) uma tentativa. É fácil, intuitivo e facilmente editável.
Verifique também a interface fluent do Mark S. Rasmussen XmlDocument, que oferece realmente uma saída XML fácil de digitar/ler.
O XmlWriter é a forma mais rápida de escrever um bom XML. XDocument, XMLDocument e alguns outros também funcionam bem, mas não são otimizados para escrever XML. Se você quiser escrever o XML o mais rápido possível, você deve definitivamente usar XmlWriter.
No passado, criei o meu esquema XML, depois usei uma ferramenta para gerar classes C# que serão serializadas nesse esquema. A Ferramenta de definição do esquema XML é um exemplo
Http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx
Penso que este recurso deve ser suficiente para uma gravação/carga XML moderada: ler / escrever XML usando C#.
A minha tarefa era guardar a notação musical. Eu escolho XML, porque eu acho que . net amadureceu o suficiente para permitir uma solução fácil para a tarefa. Eu tinha razão. Este é o meu protótipo de arquivo de música.<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>
Isso pode ser resolvido facilmente.
Para gravar no ficheiro:
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();
}
}
Para carregar o ficheiro:
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);
}
}
}
}
}
Para coisas simples, eu apenas USO As classes XmlDocument/XmlNode/XmlAttribute e o DOM XmlDocument encontrado no System.XML.
Ele gera o XML para mim, só preciso de ligar alguns itens.No entanto, em coisas maiores, eu uso serialização XML.
Para Casos simples, eu também sugeriria olhar para XmlOutput {[3] } uma interface fluente para construir Xml.
O XmlOutput é óptimo para a criação de Xml simples com código legível e de manutenção, enquanto gera Xml válido. O orginal post tem alguns grandes exemplos.
Como em cima.
Eu uso stringbuilder.acrescentar().Muito simples, e você pode então fazer xmldocument.carregar (objecto strinbuilder como parâmetro).
Provavelmente vais encontrar-te a usar o texto.concat within the append parameter, but this is a very straightforward approach.