如何转换 xml 于 DataTable?

How to convert xml to DataTable?

提问人:Headshot 提问时间:8/24/2023 最后编辑:Headshot 更新时间:8/24/2023 访问量:109

问:

我有一个内容类似于 xml 的文件,我想解析它并将数据绑定到 Datatable。我该怎么做?我的文件 xml 看起来像这样

    <StudentListSubject>
        <Member personId="1" active="yes">
          <Name id="Mary"/>
          <SubjectList>
                <Subjectvalue>Maths</Subjectvalue>
                <Subjectvalue>Literature</Subjectvalue>
          </SubjectList>
        </Member>
        <Member personId="2" active="yes">
          <Name id="John"/>
          <SubjectList>
                <Subjectvalue>Physics</Subjectvalue>
                <Subjectvalue>Maths</Subjectvalue>
                <Subjectvalue>Literature</Subjectvalue>
          </SubjectList>
        </Member>
    </StudentListSubject>

DataTable 将包含 3 列,如下所示

PersonID#ID#Subject
1#Mary#Maths,Literature
2#John#Physics,Maths,Literature

我使用XmlReader获取数据,但我不知道如何获取id和主题列表,只能获取人员id。

        var _dt = new DataTable();
        _dt.Columns.Add("ID", typeof(string));
        _dt.Columns.Add("Name", typeof(string));
        _dt.Columns.Add("Subject", typeof(string));
        var _rd = XmlReader.Create("C:\\test.xml");
        _rd.ReadToFollowing("Member");
        do
        {
            var _str = "";
            _rd.MoveToFirstAttribute();
            _str += _rd.Value; //get personID
            _rd.ReadToFollowing("Name");
            _rd.MoveToFirstAttribute();
            _str += "#" + _rd.Value; //get ID

            ////get subject list

            _dt.Rows.Add(_str.Split('#'));
        } while (_rd.ReadToFollowing("Member"));
C# XML 解析

评论

0赞 Flydog57 8/24/2023
我强烈建议您考虑创建一个类,例如,然后将 XML 读入 a 而不是 .这只是一种意见(这是 Stackoverflow——它讨厌意见),但 DataTables 很少是 2023 年几乎任何事情的正确选择public class Person { public int PersonId {get; set;} public string Name {get; set;} public List<string> Subjects {get; set;} }List<Person>DataTable

答:

0赞 Anandu 8/24/2023 #1

这是一个常用的功能你可以使用,你可以根据自己的方式进行自定义

    using System;
using System.Data;
using System.Xml;

public class XmlToDataTableConverter
{
    public static DataTable ConvertXmlToDataTable(string xmlFilePath)
    {
         
        DataTable dataTable = new DataTable();

        try
        {
            
            using (XmlTextReader xmlReader = new XmlTextReader(xmlFilePath))
            {
                
                DataSet dataSet = new DataSet();
                dataSet.ReadXml(xmlReader);
                if (dataSet.Tables.Count > 0)
                {
                    
                    dataTable = dataSet.Tables[0];
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
        }

        return dataTable;
    }
    
    string xmlFilePath = "data.xml";
    private Void ConvertToDataTable()
    {
DataTable dataTable = XmlToDataTableConverter.ConvertXmlToDataTable(xmlFilePath);

    }


}
0赞 Anandu 8/24/2023 #2

这是另一种方式

public DataTable CreateDataTableFromXML(string XmlFile)    
{  
  
    XmlDocument doc = new XmlDocument();    
    
    doc.Load(XmlFile);    
    
    DataTable Dt = new DataTable();    
    
    try    
    {    
        Dt.TableName = GetTableName(XmlFile);    
        XmlNode NodoEstructura = doc.DocumentElement.ChildNodes.Cast().ToList()[0];    
        
        foreach (XmlNode columna in NodoEstructura.ChildNodes)    
        {    
            Dt.Columns.Add(columna.Name, typeof(String));    
            
        }    
    
        XmlNode Filas = doc.DocumentElement;    
         
        foreach (XmlNode Fila in Filas.ChildNodes)    
        {    
            List<string> Valores = Fila.ChildNodes.Cast().ToList().Select(x => x.InnerText).ToList();    
            Dt.Rows.Add(Valores.ToArray());    
            Progress();    
        }    
    }    
    catch (Exception ex)    
    {    
    
    }    
    return Dt;    
}
1赞 Hossein Sabziani 8/24/2023 #3

您可以使用 prase .请记住添加此引用XDocument.Parsexml Fileusing System.Xml.Linq;

    string xml = File.ReadAllText("yourFile");

    XDocument doc = XDocument.Parse(xml);

    DataTable dataTable = new DataTable();
    dataTable.Columns.Add("PersonID");
    dataTable.Columns.Add("ID");
    dataTable.Columns.Add("Subject");

    foreach (var member in doc.Descendants("Member"))
    {
        string personId = member.Attribute("personId").Value;
        string id = member.Element("Name").Attribute("id").Value;
        string subjects = string.Join(",", member.Descendants("Subjectvalue").Select(sv => sv.Value));

        dataTable.Rows.Add(personId, id, subjects);
    }

请参阅此代码:Fiddle

评论

0赞 Headshot 8/24/2023
我明白你的意思,但我不知道我们可以与xmlReader一起使用吗?我已经更新了上面的代码。
0赞 Headshot 8/24/2023
顺便说一句,当我调试你的代码时,它退出循环,没有任何元素,我混淆了这一行(var member in doc.Descendants("Member"))
0赞 Hossein Sabziani 8/24/2023
@Headshot dotnetfiddle.net/A3u52f 看到此链接。这部分代码采用您可以访问的内部节点،,并将其放在Member tagmember variable
0赞 Hossein Sabziani 8/24/2023
@Headshot ,可以将数据表打印到控制台datatable is created and exits the loop
0赞 Headshot 8/24/2023
不,我的意思是当我调试时,这条线会断开,没有循环并且不会获得值。这就是数据表不值的原因。foreach (var member in doc.Descendants("Member"))
1赞 Serge 8/24/2023 #4

你可以使用 json

using Newtonsoft.Json;

    XElement x = XElement.Parse(xml);
    JArray jArr = JObject.Parse(JsonConvert.SerializeXNode(x)).SelectToken("StudentListSubject.Member");

    DataTable dt = new JArray(jArr.Select(a => new JObject
    {
        ["PersonId"] = a["@personId"],
        ["ID"] = a["Name"]["@id"],
        ["Subject"] = string.Join(",", a["SubjectList"]["Subjectvalue"])
    }))
    .ToObject<DataTable>();

    XDocument doc = XDocument.Parse(xml);
    DataTable dt = new JArray(
    doc.Descendants("Member")
       .Select(a => new JObject
       {
           ["PersonId"] = a.Attribute("personId").Value,
           ["ID"] = a.Element("Name").Attribute("id").Value,
           ["Subject"] = string.Join(",", a.Descendants("Subjectvalue").Select(sv => sv.Value))
       }))
       .ToObject<DataTable>()