C #에서 XML을 작성하는 방법


438

C #에서 유효한 XML을 어떻게 생성 할 수 있습니까?

답변:


510

시나리오에 따라 다릅니다. 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등)은 빠르게 많은 메모리를 사용합니다. 따라서 CSV 에서 100MB XML 파일을 작성하는 경우 다음을 고려할 수 있습니다 XmlWriter. 이것은 더 원시적이지만 (한 번만 쓰는 firehose) 매우 효율적입니다 (여기에서 큰 루프를 상상하십시오).

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).


10
XStreamingElement, msdn.microsoft.com/en-us/library/…를 잊지 마십시오 . :)
Todd White

1
XmlWriter 예제의 경우 제대로 작동하려면 마지막에 라이터를 닫아야합니다. writer.WriteEndElement () 뒤에 writer.Close ()가 필요합니다.
Marko

@Marko의 말은 사실입니다. 작가를 올바르게 닫는 것이 중요합니다. writer.Close ()를 직접 호출하는 대신 다른 방법이 있습니다. 다음과 같이 using 문에서 Create ()에 대한 호출을 래핑 할 수 있습니다. using (XmlWriter writer = XmlWriter.Create (Console.Out)) {writer.WriteStartElement ( "Foo"); etc} XmlWriter의 또 다른 (약간 향상된) 예제가 있습니다 : dotnetperls.com/xmlwriter
Morten

@Morten XmlWriter가 IDisposable을 구현하는 경우에는 statement를 사용하는 것이 가장 좋습니다.
Marko

좋은 오래된 XMLDocument에는 모든 것이 있습니다. XML 문서를 작성하는 경우 간단하고 간단하며 명확합니다.
FrenkyB

60

내가 시도한 가장 좋은 점은 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 또한 LINQ에서 XML까지 XElement 형식의 요소를 생성합니다.


이 코드가 작동하지 않는 것 같습니다. 내가 이렇게 이렇게 rty 적용에 저장 기능이 없습니다RootElement
DanilGholtsman

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

10

XmlWriter는 좋은 XML을 작성하는 가장 빠른 방법입니다. XDocument, XMLDocument 및 기타 일부는 잘 작동하지만 XML 작성에 최적화되지 않았습니다. 가능한 빨리 XML을 작성하려면 XmlWriter를 사용해야합니다.


6
즉, 컴퓨터 가 가능한 빨리 XML을 작성하도록 하려는 경우 입니다. 개발자가 가장 쉽고 자연스러운 방법으로 XML을 만들려면 XmlWriter가 해결책이 아닙니다!
sjy


4

이 리소스는 적당한 XML 저장 /로드 : C #을 사용하여 XML 읽기 / 쓰기에 충분해야한다고 생각합니다 .

내 임무는 음악 표기법을 저장하는 것이 었습니다. .NET 이 작업을 쉽게 해결할 수있을 정도로 성숙해 졌기 때문에 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);
            }
    }
}

}
}

1

간단한 것은 System.XML에있는 XmlDocument / XmlNode / XmlAttribute 클래스와 XmlDocument DOM을 사용하는 것입니다.

그것은 나를 위해 XML을 생성하므로 몇 가지 항목을 함께 연결하면됩니다.

그러나 더 큰 것은 XML 직렬화를 사용하는 것입니다.


1

간단한 경우에는 XmlOutput을 Xml 빌드를위한 유창한 인터페이스로 보는 것이 좋습니다 .

XmlOutput은 유효한 Xml을 생성하면서 읽을 수 있고 유지 관리 가능한 코드로 간단한 Xml을 만드는 데 유용합니다. 의 orginal 포스트는 훌륭한 예제가 있습니다.


-3

위와 같이.

stringbuilder.append ()를 사용합니다.

매우 간단하며 xmldocument.load (strinbuilder 객체를 매개 변수로) 할 수 있습니다.

append 매개 변수 내에서 string.concat을 사용하는 것을 알 수 있지만 이것은 매우 간단한 접근 방식입니다.


11
무언가를 올바르게 인코딩하지 않고 불법 Xml을 쓰는 것을 제외하고는 예외입니다.
Robert Paulson 2011

3
이 답변은 절대적으로 엉망이되었지만이 질문을 바탕으로 XML을 빌드하는 내 구현 중 하나를 살펴 보았습니다. 내 특정 프로젝트에서 StringBuilder를 통해 빌드하면 XDocument / XmlWriter를 사용하는 것보다 처리 시간이 10 % 빠릅니다. 그러나 XML에 익숙하다고 느끼면 특정 프로젝트에 적합합니다. (참고로 최종 XML 크기는 약 3.4MB이며 8000 줄 이상입니다.)
James Skemp

2
응용 프로그램 성능 (여기서는 밀리 초 개선 사항을 말하고 있습니까?)과 응용 프로그램 유지 관리 (기술자가 지금 변경하기 전에 한 시간 동안 코드를 숙지해야합니까) 사이의 균형을 측정했는지 궁금합니다.
Dan Esparza
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.