如何在 C# 中为复杂(更深层次)XML 输出创建数据集?

How to create a dataset for complex (deeper hierarchy) XML output in C#?

我以前从未使用过数据集,但现在我想创建一个数据集,它产生的 XML 输出完全如下:

<candidatelist>
  <comment>
    created 15.03.2016
  </comment>
  <candidates> 
    <candidate>
      <personalinfo>
        <name>Parker</name>
        <firstname>Peter</firstname>
        <sex>M</sex>
        <birthday>19.02.1993</birthday>
        <group>group1</group>
        <language>E</language>
        <type>H</type>
      </personalinfo>
      <items>
        <item>item1</item>
        <item>item2</item>
        <item>item3</item>
        <item>item4</item>
        <item>item5</item>
        <item>item6</item>
        <item>item7</item>
        <item>item8</item>
      </items>
    </candidate>
    <candidate>
      ...
    </candidate>
    ...
  </candidates>
</candidatelist>

我的方法是:创建一个包含 "name"、"firstname" 列的数据表 "personalinfo",以及一个包含 [=23] 列的数据表 "items" =].然后我可以创建一个名为 "candidate" 的数据集并像这样添加两个表:

DataTable table1 = new DataTable("personalinfo");
table1.Columns.Add("name");
table1.Columns.Add("firstname");
...
table1.Rows.Add("Parker", "Peter", ...);

DataTable table2 = new DataTable("items");
table2.Columns.Add("item");
table2.Rows.Add("item1");
table2.Rows.Add("item2");
...

DataSet set = new DataSet("candidate");
set.Tables.Add(table1);
set.Tables.Add(table2);

但是我怎样才能将几个候选者添加到一个新集合 "candidates" 并将这个新集合(与 "comment" 一起)添加到一个名为 "candidatelist" 的集合中?

尝试这样的事情

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;

namespace ConsoleApplication85
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<candidatelist>" +
                  "<comment>" +
                    "created 15.03.2016" +
                  "</comment>" +
                  "<candidates>" +
                    "<candidate>" +
                      "<personalinfo>" +
                        "<name>Parker</name>" +
                        "<firstname>Peter</firstname>" +
                        "<sex>M</sex>" +
                        "<birthday>19.02.1993</birthday>" +
                        "<group>group1</group>" +
                        "<language>E</language>" +
                        "<type>H</type>" +
                      "</personalinfo>" +
                      "<items>" +
                        "<item>item1</item>" +
                        "<item>item2</item>" +
                        "<item>item3</item>" +
                        "<item>item4</item>" +
                        "<item>item5</item>" +
                        "<item>item6</item>" +
                        "<item>item7</item>" +
                        "<item>item8</item>" +
                      "</items>" +
                    "</candidate>" +
                    "<candidate>" +
                      "<personalinfo>" +
                        "<name>Parker</name>" +
                        "<firstname>Peter</firstname>" +
                        "<sex>M</sex>" +
                        "<birthday>19.02.1993</birthday>" +
                        "<group>group1</group>" +
                        "<language>E</language>" +
                        "<type>H</type>" +
                      "</personalinfo>" +
                      "<items>" +
                        "<item>item1</item>" +
                        "<item>item2</item>" +
                        "<item>item3</item>" +
                        "<item>item4</item>" +
                        "<item>item5</item>" +
                        "<item>item6</item>" +
                        "<item>item7</item>" +
                        "<item>item8</item>" +
                      "</items>" +
                    "</candidate>" +
                  "</candidates>" +
                "</candidatelist>";

            XDocument doc = XDocument.Parse(xml);

            DataTable dt = new DataTable();
            dt.Columns.Add("name", typeof(string));
            dt.Columns.Add("firstname", typeof(string));
            dt.Columns.Add("sex", typeof(string));
            dt.Columns.Add("birthday", typeof(string));
            dt.Columns.Add("group", typeof(string));
            dt.Columns.Add("language", typeof(string));
            dt.Columns.Add("type", typeof(string));
            dt.Columns.Add("item1", typeof(string));
            dt.Columns.Add("item2", typeof(string));
            dt.Columns.Add("item3", typeof(string));
            dt.Columns.Add("item4", typeof(string));
            dt.Columns.Add("item5", typeof(string));
            dt.Columns.Add("item6", typeof(string));
            dt.Columns.Add("item7", typeof(string));
            dt.Columns.Add("item8", typeof(string));
            dt.Columns.Add("item9", typeof(string));
            dt.Columns.Add("item10", typeof(string));

            List<XElement> candidates = doc.Descendants("candidate").ToList();

            foreach (XElement candidate in candidates)
            {
                DataRow newRow = dt.Rows.Add();
                newRow["name"] = (string)candidate.Descendants("name").FirstOrDefault();
                newRow["firstname"] = (string)candidate.Descendants("firstname").FirstOrDefault();
                newRow["sex"] = (string)candidate.Descendants("sex").FirstOrDefault();
                newRow["birthday"] = (string)candidate.Descendants("birthday").FirstOrDefault();
                newRow["group"] = (string)candidate.Descendants("group").FirstOrDefault();
                newRow["language"] = (string)candidate.Descendants("language").FirstOrDefault();
                newRow["type"] = (string)candidate.Descendants("type").FirstOrDefault();

                List<string> items = candidate.Descendants("item").Select(x => (string)x).ToList();
                for (int index = 1; index <= items.Count; index++)
                {
                    newRow["item" + index.ToString()] = items[index - 1];
                }


            }

        }
    }
}

试试这个....(对于 XmlSerializer)

代码首先创建了一个candidatelist实例,添加了两个candidates ,然后将数据序列化为 XML 文件中名为 test.xml 的文件(位于应用程序的构建文件夹中)。该示例还演示了将 XML 反序列化为来自 XML 的候选列表(在 test.xml 文件中)

使用.....

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;

类.......

[XmlRoot(ElementName = "personalinfo")]
public class Personalinfo
{
    [XmlElement(ElementName = "name")]
    public string Name { get; set; }
    [XmlElement(ElementName = "firstname")]
    public string Firstname { get; set; }
    [XmlElement(ElementName = "sex")]
    public string Sex { get; set; }
    [XmlElement(ElementName = "birthday")]
    public string Birthday { get; set; }
    [XmlElement(ElementName = "group")]
    public string Group { get; set; }
    [XmlElement(ElementName = "language")]
    public string Language { get; set; }
    [XmlElement(ElementName = "type")]
    public string Type { get; set; }
}

[XmlRoot(ElementName = "items")]
public class Items
{
    public Items()
    {
        this.Item = new List<string>();
    }
    [XmlElement(ElementName = "item")]
    public List<string> Item { get; set; }
}

[XmlRoot(ElementName = "candidate")]
public class Candidate
{
    public Candidate()
    {
        this.Items = new Items();
    }
    [XmlElement(ElementName = "personalinfo")]
    public Personalinfo Personalinfo { get; set; }
    [XmlElement(ElementName = "items")]
    public Items Items { get; set; }
}

[XmlRoot(ElementName = "candidates")]
public class Candidates
{
    public Candidates()
    {
        this.Candidate = new List<Candidate>();
    }
    [XmlElement(ElementName = "candidate")]
    public List<Candidate> Candidate { get; set; }
}

[XmlRoot(ElementName = "candidatelist")]
public class Candidatelist
{
    public Candidatelist()
    {
        this.Candidates = new Candidates();
    }
    [XmlElement(ElementName = "comment")]
    public string Comment { get; set; }
    [XmlElement(ElementName = "candidates")]
    public Candidates Candidates { get; set; }
}

代码......

    private void Form1_Load(object sender, EventArgs e)
    {
        try
        {
            Candidatelist Candidatelist = new Candidatelist();
            Candidatelist.Comment = "created 15.03.2016";

            Candidate candidate1 = new Candidate();
            candidate1.Personalinfo = new Personalinfo() { Name = "Parker", Firstname = "Peter", Sex = "M", Birthday = "19.02.1993", Group = "group1", Language = "E", Type = "H" };
            candidate1.Items.Item.Add("Item1");
            candidate1.Items.Item.Add("Item2");
            candidate1.Items.Item.Add("Item3");
            candidate1.Items.Item.Add("Item4");
            candidate1.Items.Item.Add("Item5");
            candidate1.Items.Item.Add("Item6");
            candidate1.Items.Item.Add("Item7");
            candidate1.Items.Item.Add("Item8");

            Candidatelist.Candidates.Candidate.Add(candidate1);

            Candidate candidate2 = new Candidate();
            candidate2.Personalinfo = new Personalinfo() { Name = "John", Firstname = "Doe", Sex = "M", Birthday = "19.02.1993", Group = "group1", Language = "E", Type = "H" };
            candidate2.Items.Item.Add("Item1");
            candidate2.Items.Item.Add("Item2");
            candidate2.Items.Item.Add("Item3");
            candidate2.Items.Item.Add("Item4");
            candidate2.Items.Item.Add("Item5");
            candidate2.Items.Item.Add("Item6");
            candidate2.Items.Item.Add("Item7");
            candidate2.Items.Item.Add("Item8");

            Candidatelist.Candidates.Candidate.Add(candidate2);

            // and to Serialize to XML
            Serialize(Candidatelist);

            // and to Deserialize from XML
            Candidatelist deserializedCandidatelist = Deserialize<Candidatelist>();

        }
        catch (Exception ex)
        {
            throw;
        }

    }

    private static void Serialize<T>(T data)
    {

        // Use a file stream here.
        using (TextWriter WriteFileStream = new StreamWriter("test.xml"))
        {
            // Construct a SoapFormatter and use it  
            // to serialize the data to the stream.
            XmlSerializer SerializerObj = new XmlSerializer(typeof(T));

            try
            {
                // Serialize EmployeeList to the file stream
                SerializerObj.Serialize(WriteFileStream, data);
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Failed to serialize. Reason: {0}", ex.Message));
            }
        }
    }

    private static T Deserialize<T>() where T : new()
    {
        //List<Employee> EmployeeList2 = new List<Employee>();
        // Create an instance of T
        T ReturnListOfT = CreateInstance<T>();


        // Create a new file stream for reading the XML file
        using (FileStream ReadFileStream = new FileStream("test.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            // Construct a XmlSerializer and use it  
            // to serialize the data from the stream.
            XmlSerializer SerializerObj = new XmlSerializer(typeof(T));
            try
            {
                // Deserialize the hashtable from the file
                ReturnListOfT = (T)SerializerObj.Deserialize(ReadFileStream);
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Failed to serialize. Reason: {0}", ex.Message));
            }

        }
        // return the Deserialized data.
        return ReturnListOfT;
    }

    // function to create instance of T
    public static T CreateInstance<T>() where T : new()
    {
        return (T)Activator.CreateInstance(typeof(T));
    }

XML(来自 test.xml)

<?xml version="1.0" encoding="utf-8"?>
<candidatelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <comment>created 15.03.2016</comment>
  <candidates>
    <candidate>
      <personalinfo>
        <name>Parker</name>
        <firstname>Peter</firstname>
        <sex>M</sex>
        <birthday>19.02.1993</birthday>
        <group>group1</group>
        <language>E</language>
        <type>H</type>
      </personalinfo>
      <items>
        <item>Item1</item>
        <item>Item2</item>
        <item>Item3</item>
        <item>Item4</item>
        <item>Item5</item>
        <item>Item6</item>
        <item>Item7</item>
        <item>Item8</item>
      </items>
    </candidate>
    <candidate>
      <personalinfo>
        <name>John</name>
        <firstname>Doe</firstname>
        <sex>M</sex>
        <birthday>19.02.1993</birthday>
        <group>group1</group>
        <language>E</language>
        <type>H</type>
      </personalinfo>
      <items>
        <item>Item1</item>
        <item>Item2</item>
        <item>Item3</item>
        <item>Item4</item>
        <item>Item5</item>
        <item>Item6</item>
        <item>Item7</item>
        <item>Item8</item>
      </items>
    </candidate>
  </candidates>
</candidatelist>