How can I build XML in C#?

前端 未结 9 1664

How can I generate valid XML in C#?

相关标签:
9条回答
  • 2020-11-22 06:50

    The best thing hands down that I have tried is LINQ to XSD (which is unknown to most developers). You give it an XSD Schema and it generates a perfectly mapped complete strongly-typed object model (based on LINQ to XML) for you in the background, which is really easy to work with - and it updates and validates your object model and XML in real-time. While it's still "Preview", I have not encountered any bugs with it.

    If you have an XSD Schema that looks like this:

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

    Then you can simply build XML like this:

    RootElement rootElement = new RootElement;
    rootElement.Element1 = "Element1";
    rootElement.Element2 = "Element2";
    rootElement.Attribute1 = 5;
    rootElement.Attribute2 = true;
    

    Or simply load an XML from file like this:

    RootElement rootElement = RootElement.Load(filePath);
    

    Or save it like this:

    rootElement.Save(string);
    rootElement.Save(textWriter);
    rootElement.Save(xmlWriter);
    

    rootElement.Untyped also yields the element in form of a XElement (from LINQ to XML).

    0 讨论(0)
  • 2020-11-22 06:50

    As above.

    I use stringbuilder.append().

    Very straightforward, and you can then do xmldocument.load(strinbuilder object as parameter).

    You will probably find yourself using string.concat within the append parameter, but this is a very straightforward approach.

    0 讨论(0)
  • 2020-11-22 06:55

    I think this resource should suffice for a moderate XML save/load: Read/Write XML using C#.

    My task was to store musical notation. I choose XML, because I guess .NET has matured enough to allow easy solution for the task. I was right :)

    This is my song file prototype:

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

    That can be solved quite easily:

    For Save to File:

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

    For load file:

    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);
                }
        }
    }
    
    }
    }
    
    0 讨论(0)
  • 2020-11-22 06:59
    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)
                             )
                );
    
    0 讨论(0)
  • 2020-11-22 07:02

    For simple things, I just use the XmlDocument/XmlNode/XmlAttribute classes and XmlDocument DOM found in System.XML.

    It generates the XML for me, I just need to link a few items together.

    However, on larger things, I use XML serialization.

    0 讨论(0)
  • 2020-11-22 07:03

    It depends on the scenario. XmlSerializer is certainly one way and has the advantage of mapping directly to an object model. In .NET 3.5, XDocument, etc. are also very friendly. If the size is very large, then XmlWriter is your friend.

    For an XDocument example:

    Console.WriteLine(
        new XElement("Foo",
            new XAttribute("Bar", "some & value"),
            new XElement("Nested", "data")));
    

    Or the same with 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);
    

    If you are writing a large stream of data, then any of the DOM approaches (such as XmlDocument/XDocument, etc.) will quickly take a lot of memory. So if you are writing a 100 MB XML file from CSV, you might consider XmlWriter; this is more primitive (a write-once firehose), but very efficient (imagine a big loop here):

    XmlWriter writer = XmlWriter.Create(Console.Out);
    writer.WriteStartElement("Foo");
    writer.WriteAttributeString("Bar", "Some & value");
    writer.WriteElementString("Nested", "data");
    writer.WriteEndElement();
    

    Finally, via 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);
    

    This is a nice model for mapping to classes, etc.; however, it might be overkill if you are doing something simple (or if the desired XML doesn't really have a direct correlation to the object model). Another issue with XmlSerializer is that it doesn't like to serialize immutable types : everything must have a public getter and setter (unless you do it all yourself by implementing IXmlSerializable, in which case you haven't gained much by using XmlSerializer).

    0 讨论(0)
提交回复
热议问题