Как я могу создать XML на C #?

Как я могу сгенерировать действительный XML на C #?


person Community    schedule 12.11.2008    source источник


Ответы (8)


Это зависит от сценария. 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 (например, _8 _ / _ 9_ и т. Д.) Быстро займет много памяти. Поэтому, если вы пишете XML-файл размером 100 МБ из 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 заключается в том, что он не любит сериализовать неизменяемые типы: у всего должны быть общедоступные методы получения и (если вы не сделаете все это самостоятельно, реализовав IXmlSerializable, и в этом случае вы не получили много, используя XmlSerializer).

person Marc Gravell    schedule 12.11.2008
comment
Не забывайте о XStreamingElement, msdn.microsoft.com / ru-ru / library /. :) - person Todd White; 12.11.2008
comment
Для примера XmlWriter важно отметить, что вам нужно закрыть писатель в конце, чтобы он работал правильно - writer.Close () требуется после writer.WriteEndElement (). - person Marko; 03.03.2015
comment
Это правда, что говорит @Marko: важно правильно закрыть писателя. Есть также другой способ сделать это вместо прямого вызова writer.Close (). Вы можете заключить вызов Create () в оператор using следующим образом: using (XmlWriter writer = XmlWriter.Create (Console.Out)) {writer.WriteStartElement (Foo); etc} Здесь есть еще один (немного более усовершенствованный) пример XmlWriter: dotnetperls.com/xmlwriter - person Morten; 10.10.2018
comment
@Morten Конечно, если XmlWriter реализует IDisposable, тогда оператор using - лучший вариант. - person Marko; 11.10.2018
comment
В старом добром XMLDocument есть все. Прямо, просто и понятно, если вы создаете XML-документ. - person FrenkyB; 23.05.2019

Лучшее, что я пробовал, - это LINQ to 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).

person Community    schedule 01.09.2009
comment
похоже, что этот код не рабочий код. когда я пытаюсь сделать это, к RootElement не применяется функция сохранения. - person DanilGholtsman; 31.03.2014

XmlWriter - это самый быстрый способ написать хороший XML. XDocument, XMLDocument и некоторые другие также работают хорошо, но не оптимизированы для написания XML. Если вы хотите писать XML как можно быстрее, вам обязательно следует использовать XmlWriter.

person Mikael Söderström    schedule 12.11.2008
comment
То есть, если вы хотите, чтобы компьютер записывал XML как можно быстрее. Если вы, разработчик, хотите создать XML самым простым и естественным способом, XmlWriter, вероятно, не решение! - person sjy; 24.02.2014

В прошлом я создал свою схему XML, а затем использовал инструмент для создания классов C #, которые будут сериализованы в эту схему. Инструмент определения схемы XML является одним из примеров

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

person Bob    schedule 12.11.2008

Я думаю, что этого ресурса должно хватить для умеренного сохранения / загрузки XML: Чтение / запись XML с использованием C #.

Моей задачей было хранить нотную запись. Я выбираю XML, потому что полагаю, .NET достаточно зрел, чтобы обеспечить простое решение этой задачи. Я был прав :)

Это прототип файла с моей песней:

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

}
}
person Community    schedule 10.12.2010

Для простых вещей я просто использую классы XmlDocument / XmlNode / XmlAttribute и XmlDocument DOM из System.XML.

Он генерирует для меня XML, мне просто нужно связать несколько элементов вместе.

Однако в более крупных вещах я использую сериализацию XML.

person FlySwat    schedule 12.11.2008

Для простых случаев я бы также предложил посмотреть XmlOutput a свободный интерфейс для создания Xml.

XmlOutput отлично подходит для простого создания Xml с читаемым и поддерживаемым кодом при создании действительного Xml. В оригинальном сообщении есть несколько отличных примеров.

person Todd    schedule 12.11.2008

Как указано выше.

Я использую stringbuilder.append ().

Очень просто, и затем вы можете выполнить xmldocument.load (объект strinbuilder в качестве параметра).

Вы, вероятно, обнаружите, что используете string.concat в параметре добавления, но это очень простой подход.

person GurdeepS    schedule 12.11.2008
comment
За исключением случаев, когда вы забываете что-то правильно кодировать и пишете недопустимый Xml. - person Robert Paulson; 14.11.2008
comment
Этот ответ был полностью отвергнут, но, основываясь на этом вопросе, я взглянул на одну из моих собственных реализаций, в которой я создаю XML. В моем конкретном проекте я постоянно обнаруживал, что сборка с помощью StringBuilder приводит к увеличению времени обработки на 10% по сравнению с использованием XDocument / XmlWriter. Но я чувствую себя комфортно с XML, и это для моего конкретного проекта. (Для справки, окончательный размер XML составляет около 3,4 МБ, при этом более 8000 строк.) - person James Skemp; 24.10.2010
comment
Мне было бы любопытно узнать, измерили ли вы компромисс между производительностью приложения (мы говорим об улучшениях в миллисекундах?) И обслуживанием приложения (нужно ли вашим инженерам в течение часа знакомиться с кодом, прежде чем вносить изменения сейчас?) - person Dan Esparza; 10.08.2011