ฉันจะสร้าง XML ใน C # ได้อย่างไร


คำตอบ:


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ฯลฯ ) ได้อย่างรวดเร็วจะใช้หน่วยความจำมาก ดังนั้นหากคุณกำลังเขียนไฟล์ XML 100 MB จากCSVคุณอาจพิจารณา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/… . :)
ทอดด์ไวท์

1
สำหรับตัวอย่าง XmlWriter มันเป็นสิ่งสำคัญที่จะต้องทราบว่าคุณต้องปิดตัวเขียนในตอนท้ายเพื่อให้มันทำงานได้อย่างถูกต้อง - writer.Close () เป็นสิ่งจำเป็นหลังจากตัวเขียน.WriteEndElement ()
Marko

มันเป็นความจริงที่ @Marko พูดว่า: มันเป็นเรื่องสำคัญที่จะต้องปิดนักเขียนให้เหมาะสม นอกจากนี้ยังมีวิธีอื่นในการทำเช่นนั้นแทนการเรียก writer.Close () โดยตรง คุณสามารถตัดการเรียกไปที่สร้าง () ในคำสั่งการใช้ดังนี้: using (XmlWriter writer = XmlWriter.Create (Console.Out)) {writer.WriteStartElement ("Foo"); ฯลฯ } มีอีกตัวอย่างหนึ่งของ XmlWriter ที่ได้รับการปรับปรุงเพิ่มเติม: dotnetperls.com/xmlwriter
Morten

@Morten แน่ใจว่า XmlWriter ใช้ IDisposable แล้วใช้คำสั่งเป็นตัวเลือกที่ดีที่สุด
Marko

XMLDocument เก่าดีมีทุกอย่าง ตรงไปตรงมาง่ายและชัดเจนหากคุณกำลังสร้างเอกสาร XML
FrenkyB

60

สิ่งที่ดีที่สุดที่ฉันได้ลองคือLINQ to XSD (ซึ่งเป็นที่รู้จักของนักพัฒนาส่วนใหญ่) คุณให้ Xema Schema และสร้างโมเดลวัตถุที่พิมพ์อย่างสมบูรณ์ที่แมปอย่างสมบูรณ์ (อิง LINQ ถึง XML) สำหรับคุณในพื้นหลังซึ่งง่ายต่อการใช้งานจริง ๆ - และจะอัปเดตและตรวจสอบโมเดลวัตถุและ XML ของคุณใน เวลาจริง ในขณะที่ยังเป็น "ตัวอย่าง" ฉันไม่พบข้อบกพร่องใด ๆ

หากคุณมี XSD Schema ที่มีลักษณะเช่นนี้:

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


ดูเหมือนว่ารหัสนี้จะไม่ทำงานรหัส เมื่อฉัน rty ทำเช่นนี้ไม่มีบันทึก fucntion นำไปใช้กับ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 Schema ของฉันจากนั้นใช้เครื่องมือในการสร้างคลาส C # ซึ่งจะทำให้เป็นอันดับกับสคีมานั้น เครื่องมือการกำหนด XML Schema เป็นหนึ่งในตัวอย่าง

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


4

ฉันคิดว่าทรัพยากรนี้ควรพอเพียงสำหรับการบันทึก / โหลด 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);
            }
    }
}

}
}

1

สำหรับสิ่งง่ายๆฉันใช้คลาส XmlDocument / XmlNode / XmlAttribute และ XmlDocument DOM ที่พบใน System.XML

มันสร้าง XML ให้ฉันฉันแค่ต้องเชื่อมโยงบางรายการเข้าด้วยกัน

อย่างไรก็ตามในสิ่งที่ใหญ่กว่าฉันใช้ XML เป็นอันดับ


1

สำหรับกรณีง่าย ๆ ฉันขอแนะนำให้ดูที่XmlOutputอินเทอร์เฟซที่คล่องแคล่วสำหรับการสร้าง Xml

XmlOutput เหมาะสำหรับการสร้าง Xml แบบง่าย ๆ ด้วยโค้ดที่อ่านได้และบำรุงรักษาได้ในขณะที่สร้าง Xml ที่ถูกต้อง โพสต์เดิมมีตัวอย่างที่ดีบางอย่าง


-3

ดังกล่าวข้างต้น

ฉันใช้ stringbuilder.append ()

ตรงไปตรงมามากและคุณสามารถทำ xmldocument.load (วัตถุ strinbuilder เป็นพารามิเตอร์)

คุณอาจจะพบว่าตัวเองใช้ string.concat ภายในพารามิเตอร์ผนวก แต่นี่เป็นวิธีที่ตรงไปตรงมามาก


11
ยกเว้นเมื่อคุณลืมเข้ารหัสสิ่งที่ถูกต้องและเขียน Xml ที่ผิดกฎหมาย
Robert Paulson

3
คำตอบนี้ถูกกระแทกอย่างสมบูรณ์ แต่จากคำถามนี้ฉันดูที่การใช้งานของตัวเองที่ฉันสร้าง XML สำหรับโครงการเฉพาะของฉันฉันพบว่าการสร้างผ่าน StringBuilder ทำให้การประมวลผลเร็วกว่าการใช้ XDocument / XmlWriter 10% แต่ฉันรู้สึกสะดวกสบายกับ XML และสำหรับโครงการเฉพาะของฉัน (สำหรับการอ้างอิงขนาด XML สุดท้ายจะอยู่ที่ประมาณ 3.4 MB และมีมากกว่า 8000 บรรทัด)
James Skemp

2
ฉันอยากรู้ว่าคุณวัดการแลกเปลี่ยนระหว่างประสิทธิภาพของแอปพลิเคชัน (เรากำลังพูดถึงการปรับปรุงมิลลิวินาทีที่นี่หรือไม่) และการบำรุงรักษาแอปพลิเคชัน (วิศวกรของคุณจำเป็นต้องทำความคุ้นเคยกับโค้ดเป็นเวลาหนึ่งชั่วโมงก่อนทำการเปลี่ยนแปลงหรือไม่)
Dan Esparza
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.