




Это зависит от сценария. XmlSerializer, безусловно, является односторонним и имеет то преимущество, что он напрямую отображает объектную модель. В .NET 3.5 XDocument и т. д. Также очень дружелюбны. Если размер очень большой, то XmlWriter - ваш друг.
Для примера XDocument:
Console.WriteLine(
new XElement("Foo",
new XAttribute("Bar", "some & value"),
new XElement("Nested", "data")));
Или то же самое с 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);
Если вы пишете поток данных большой, то любой из подходов DOM (например, XmlDocument / XDocument и т. д.) Быстро займет много памяти. Итак, если вы пишете XML-файл размером 100 MB из CSV, вы можете рассмотреть XmlWriter; это более примитивно (пожарный шланг с однократной записью), но очень эффективно (представьте себе большой цикл):
XmlWriter writer = XmlWriter.Create(Console.Out);
writer.WriteStartElement("Foo");
writer.WriteAttributeString("Bar", "Some & value");
writer.WriteElementString("Nested", "data");
writer.WriteEndElement();
Наконец, через 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);
Это хорошая модель для отображения на классы и т. Д .; однако это может оказаться излишним, если вы делаете что-то простое (или если желаемый XML не имеет прямого отношения к объектной модели). Другая проблема с XmlSerializer заключается в том, что он не любит сериализовать неизменяемые типы: все должно иметь общедоступный геттер и setter (если вы не сделаете все это самостоятельно, реализовав IXmlSerializable, и в этом случае вы не многого добились, используя XmlSerializer).
Для примера XmlWriter важно отметить, что вам нужно закрыть писатель в конце, чтобы он работал правильно - writer.Close () требуется после writer.WriteEndElement ().
Это правда, что говорит @Marko: важно правильно закрыть писателя. Есть также другой способ сделать это вместо прямого вызова writer.Close (). Вы можете заключить вызов Create () в оператор using следующим образом: using (XmlWriter writer = XmlWriter.Create (Console.Out)) {writer.WriteStartElement ("Foo"); etc} Здесь есть еще один (немного более расширенный) пример XmlWriter: dotnetperls.com/xmlwriter
@Morten Конечно, если XmlWriter реализует IDisposable, тогда оператор using - лучший вариант.
В старом добром XMLDocument есть все. Прямо, просто и понятно, если вы создаете XML-документ.
XmlWriter - самый быстрый способ написать хороший XML. XDocument, XMLDocument и некоторые другие также работают хорошо, но не оптимизированы для написания XML. Если вы хотите писать XML как можно быстрее, вам обязательно следует использовать XmlWriter.
То есть, если вы хотите, чтобы компьютер записывал XML как можно быстрее. Если вы, разработчик, хотите создать XML самым простым и естественным способом, XmlWriter, вероятно, не решение!
Для простых вещей я просто использую классы XmlDocument / XmlNode / XmlAttribute и XmlDocument DOM из System.XML.
Он генерирует для меня XML, мне просто нужно связать несколько элементов вместе.
Однако в более крупных вещах я использую сериализацию XML.
В простых случаях я бы также посоветовал взглянуть на XmlOutput - свободный интерфейс для создания Xml.
XmlOutput отлично подходит для простого создания Xml с читаемым и поддерживаемым кодом при создании действительного Xml. У оригинальный пост есть несколько отличных примеров.
Раньше я создавал свою схему XML, а затем использовал инструмент для создания классов C#, которые будут сериализованы в эту схему. Инструмент определения схемы XML - один из примеров
http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx
Как указано выше.
Я использую stringbuilder.append ().
Очень просто, и затем вы можете выполнить xmldocument.load (объект strinbuilder в качестве параметра).
Вы, вероятно, обнаружите, что используете string.concat в параметре добавления, но это очень простой подход.
За исключением случаев, когда вы забываете что-то правильно кодировать и пишете недопустимый Xml.
Этот ответ был полностью отвергнут, но, основываясь на этом вопросе, я взглянул на одну из моих собственных реализаций, в которой я создаю XML. В моем конкретном проекте я постоянно обнаруживал, что сборка с помощью StringBuilder приводит к увеличению времени обработки на 10% по сравнению с использованием XDocument / XmlWriter. Но я чувствую себя комфортно с XML, и это для моего конкретного проекта. (Для справки, окончательный размер XML составляет около 3,4 МБ, при этом более 8000 строк.)
Мне было бы любопытно узнать, измерили ли вы компромисс между производительностью приложения (мы говорим об улучшениях в миллисекундах?) И обслуживанием приложения (нужно ли вашим инженерам в течение часа знакомиться с кодом, прежде чем вносить изменения сейчас?)
Лучшее, что я пробовал, - это LINQ в XSD (который неизвестен большинству разработчиков). Вы даете ему схему XSD, и он генерирует идеально сопоставленную полную строго типизированную объектную модель (на основе LINQ to XML) для вас в фоновом режиме, с которой действительно легко работать - и он обновляет и проверяет вашу объектную модель и XML в в реальном времени. Пока это еще "Предварительный просмотр", я не обнаружил в нем каких-либо ошибок.
Если у вас есть схема XSD, которая выглядит так:
<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>
Затем вы можете просто построить XML следующим образом:
RootElement rootElement = new RootElement;
rootElement.Element1 = "Element1";
rootElement.Element2 = "Element2";
rootElement.Attribute1 = 5;
rootElement.Attribute2 = true;
Или просто загрузите XML из файла следующим образом:
RootElement rootElement = RootElement.Load(filePath);
Или сохраните это так:
rootElement.Save(string);
rootElement.Save(textWriter);
rootElement.Save(xmlWriter);
rootElement.Untyped также выдает элемент в форме XElement (из LINQ в XML).
похоже, что этот код не рабочий код. когда я пытаюсь сделать это, к RootElement не применяется функция сохранения.
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)
)
);
Я думаю, что этого ресурса должно хватить для умеренного сохранения / загрузки XML: Чтение / запись XML с использованием C#.
Моей задачей было хранить нотную запись. Я выбираю XML, потому что полагаю, что .СЕТЬ достаточно повзрослел, чтобы обеспечить простое решение этой задачи. Я был прав :)
Это прототип файла с моей песней:
<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>
Это можно решить довольно легко:
Для сохранения в файл:
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();
}
}
Для загрузки файла:
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);
}
}
}
}
}
Не забывайте про XStreamingElement, msdn.microsoft.com/en-us/library/…. :)