Làm cách nào tôi có thể tạo XML hợp lệ trong C #?
Làm cách nào tôi có thể tạo XML hợp lệ trong C #?
Câu trả lời:
Nó phụ thuộc vào kịch bản. XmlSerializer
chắc chắn là một cách và có lợi thế là ánh xạ trực tiếp vào mô hình đối tượng. Trong .NET 3.5, XDocument
v.v ... cũng rất thân thiện. Nếu kích thước rất lớn, thìXmlWriter
là bạn của bạn.
Ví XDocument
dụ:
Console.WriteLine(
new XElement("Foo",
new XAttribute("Bar", "some & value"),
new XElement("Nested", "data")));
Hoặc tương tự với 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);
Nếu bạn đang viết một lượng lớn dòng dữ liệu, sau đó bất kỳ của DOM phương pháp tiếp cận (ví dụ như XmlDocument
/ XDocument
, vv) sẽ nhanh chóng mất rất nhiều bộ nhớ. Vì vậy, nếu bạn đang viết tệp XML 100 MB từ CSV , bạn có thể xem xét XmlWriter
; cái này còn nguyên thủy hơn (một loại thuốc chữa cháy một lần), nhưng rất hiệu quả (hãy tưởng tượng một vòng lặp lớn ở đây):
XmlWriter writer = XmlWriter.Create(Console.Out);
writer.WriteStartElement("Foo");
writer.WriteAttributeString("Bar", "Some & value");
writer.WriteElementString("Nested", "data");
writer.WriteEndElement();
Cuối cùng, thông qua 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);
Đây là một mô hình đẹp để ánh xạ tới các lớp, v.v.; tuy nhiên, nó có thể là quá mức nếu bạn đang làm một cái gì đó đơn giản (hoặc nếu XML mong muốn không thực sự có mối tương quan trực tiếp với mô hình đối tượng). Một vấn đề khác XmlSerializer
là nó không muốn tuần tự hóa các loại không thay đổi: mọi thứ đều phải có trình thu thập và thiết lập công khai (trừ khi bạn tự làm tất cả bằng cách thực hiện IXmlSerializable
, trong trường hợp bạn chưa đạt được nhiều bằng cách sử dụng XmlSerializer
).
Điều tốt nhất mà tôi đã thử là LINQ to XSD (điều mà hầu hết các nhà phát triển chưa biết). Bạn cung cấp cho nó một Lược đồ XSD và nó tạo ra một mô hình đối tượng được gõ hoàn toàn được ánh xạ hoàn hảo (dựa trên LINQ to XML) cho bạn trong nền, điều này thực sự dễ dàng để làm việc - và nó cập nhật và xác thực mô hình đối tượng và XML của bạn trong thời gian thực. Mặc dù vẫn là "Xem trước", tôi không gặp phải bất kỳ lỗi nào với nó.
Nếu bạn có Lược đồ XSD trông như thế này:
<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>
Sau đó, bạn có thể chỉ cần xây dựng XML như thế này:
RootElement rootElement = new RootElement;
rootElement.Element1 = "Element1";
rootElement.Element2 = "Element2";
rootElement.Attribute1 = 5;
rootElement.Attribute2 = true;
Hoặc đơn giản là tải một XML từ tệp như thế này:
RootElement rootElement = RootElement.Load(filePath);
Hoặc lưu nó như thế này:
rootElement.Save(string);
rootElement.Save(textWriter);
rootElement.Save(xmlWriter);
rootElement.Untyped
cũng mang lại thành phần dưới dạng XE đắp (từ LINQ sang XML).
RootElement
XmlWriter là cách nhanh nhất để viết XML tốt. XDocument, XMLDocument và một số thứ khác hoạt động tốt, nhưng không được tối ưu hóa để viết XML. Nếu bạn muốn viết XML càng nhanh càng tốt, bạn chắc chắn nên sử dụng XmlWriter.
Trước đây tôi đã tạo Lược đồ XML của mình, sau đó sử dụng một công cụ để tạo các lớp C # sẽ tuần tự hóa cho lược đồ đó. Công cụ định nghĩa lược đồ XML là một ví dụ
http://msdn.microsoft.com/en-us/l Library / x6c1kb0s (VS.71) .aspx
Tôi nghĩ tài nguyên này đủ cho việc lưu / tải XML vừa phải: Đọc / ghi XML bằng C # .
Nhiệm vụ của tôi là lưu trữ ký hiệu âm nhạc. Tôi chọn XML, vì tôi đoán .NET đã trưởng thành đủ để cho phép giải pháp dễ dàng cho nhiệm vụ. Tôi đã đúng :)
Đây là nguyên mẫu tập tin bài hát của tôi:
<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>
Điều đó có thể được giải quyết khá dễ dàng:
Để lưu vào tệp:
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();
}
}
Đối với tệp tải:
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);
}
}
}
}
}
Đối với các trường hợp đơn giản, tôi cũng đề nghị xem xét XmlOutput một giao diện lưu loát để xây dựng Xml.
XmlOutput rất tốt cho việc tạo Xml đơn giản với mã có thể đọc và duy trì được, trong khi tạo Xml hợp lệ. Bài viết ban đầu có một số ví dụ tuyệt vời.
Như trên.
Tôi sử dụng Stringbuilder.append ().
Rất đơn giản, và sau đó bạn có thể thực hiện xmldocument.load (đối tượng strinbuilder làm tham số).
Bạn có thể sẽ thấy mình sử dụng string.concat trong tham số chắp thêm, nhưng đây là một cách tiếp cận rất đơn giản.