【问题标题】:converting xml document to data table in C#在 C# 中将 xml 文档转换为数据表
【发布时间】:2011-12-18 18:56:25
【问题描述】:

我正在尝试读取一个简单的 Web 服务 (REST) 并在我的 C# 桌面应用程序中填充一个下拉框。我正在使用 .net 2.0

以下是我的 web 服务返回 xml

<sections type="array">
 <section>
  <name>Standing</name>
  <created-at type="datetime">2011-10-23T23:17:54+05:30</created-at>
  <updated-at type="datetime">2011-10-23T23:17:54+05:30</updated-at>
  <id type="integer">1</id>
  <status type="integer">1</status>
  <service-charge type="float">0.0</service-charge>
 </section>
 <section>
  <name>VIP</name>
  <created-at type="datetime">2011-10-30T11:27:05+05:30</created-at>
  <updated-at type="datetime">2011-10-30T11:27:05+05:30</updated-at>
  <id type="integer">2</id>
  <status type="integer">1</status>
  <service-charge type="float">10.0</service-charge>
 </section>

在下面的代码中,我试图将 xml 文档转换为数据表

  public DataTable getSections() {
    String url = "http://<site_url>/sections.xml";
    DataTable t = new DataTable();
    HttpHandler handle = new HttpHandler();
    StreamReader sr = handle.executeGET(url);
    String xml = "";
    while (sr.Peek() >= 0)
    {
        xml  += sr.ReadLine();
    }
    XmlDataDocument doc = new XmlDataDocument();
    doc.LoadXml(xml);
    XmlReader xmlReader = new XmlNodeReader(doc);
    DataSet ds = new DataSet();
    ds.ReadXml(xmlReader);
    t = ds.Tables[0];
    return t;
}

在最后一段中,我试图将它绑定到我的下拉框 (cmbSections)

DataTable t = sec.getSections();
cmbSections.DataSource = t;
cmbSections.DisplayMember = "name";
cmbSections.ValueMember = "id";

但我收到以下错误

Cannot bind to the new display member.
Parameter name: newDisplayMember

我在这里缺少什么,请帮忙,我是 C# 世界的新手

【问题讨论】:

  • 如果你在getSections的返回行下一个断点,你在DataSet中看到了什么?
  • 你有源 xml 的架构吗?
  • 嗨 Sq33G,我想我得到了一些值,但不知道如何调试,但是当我使用 't.GetType();'我得到 {System.Data.DataTable} 作为输出,有什么特殊的部分我应该看,谢谢你的回答
  • 嗨 curtisk,我不确定你对源 xml 架构的要求是什么,你能解释一下吗,谢谢
  • @sameera207,当然。 GetType() is inherited from object。您需要学习和理解您正在使用的 API。查看DataTable 上的RowsColumns 集合以回答@sq33G 的问题。

标签: c# .net xml web-services


【解决方案1】:

使用扩展方法支持 XElement 到 Datatable 的转换。您可以将此方法添加到任何实用程序类中。确保类是静态的。

public static class XElementExtensions 
{
    public static DataTable ToDataTable(this XElement element) 
    {
        DataSet ds = new DataSet();
        string rawXml = element.ToString();
        ds.ReadXml(new StringReader(rawXml));
        return ds.Tables[0];
    }


    public static DataTable ToDataTable(this IEnumerable<XElement> elements) 
    {
        return ToDataTable(new XElement("Root", elements));
    }
}

如何使用

//Add logic to store xml data in file or string & read accordingly here.
string file = Server.MapPath("~/Data.xml");
XDocument document = XDocument.Load(file);
var query = from b in document.Elements("sections").Elements("section")
                  select b;

DataTable table = query.ToDataTable();

【讨论】:

    【解决方案2】:

    将 XML 转换为 DataSet 的简单方法:

            StringReader strr = new StringReader(strXML);
            XmlTextReader xtr = new XmlTextReader(strr);
            YourTypeDataSet dstest = new YourTypeDataSet();
            dstest.ReadXml(xtr);
    
            if (dstest.Tables.Count > 0) ...
    

    为了正确转换,您将类型 DataSet 替换为: 数据集 dstest = new DataSet();

    ;)

    【讨论】:

      【解决方案3】:

      我可以使用以下代码,但我不确定这是否是正确的方法

      (这个解析上面同一个xml)

      public DataTable getSections() {
              String url = "http://<site_url>/sections.xml/sections.xml";
              DataTable t = new DataTable();
              t.Columns.Add("id", typeof(String));
              t.Columns.Add("name", typeof(String));
      
              HttpHandler handle = new HttpHandler();
              StreamReader sr = handle.executeGET(url);
              String xml = "";
              List<String> id = new List<string>();
              List<String> name = new List<string>();
      
              while (sr.Peek() >= 0)
              {
                  xml  += sr.ReadLine();
              }
              XmlDataDocument doc = new XmlDataDocument();
              doc.LoadXml(xml);
              XmlReader xmlReader = new XmlNodeReader(doc);
              while (xmlReader.Read()){
                  if (xmlReader.IsStartElement()) {
                      String b = xmlReader.Name;
                      switch (xmlReader.Name) { 
                          case "sections":
                              break;
                          case "section":
                              break;
                          case "id":
                              if (xmlReader.Read())
                              {
                                  id.Add(xmlReader.Value.Trim());
                              }
                              break;
                          case "name":
                              if (xmlReader.Read())
                              {
                                  name.Add(xmlReader.Value.Trim());
      
                              }
                              break;
      
                      }
                  }
              }
      
              int counter = 0;
      
              foreach (String i in id) {
                  DataRow r = t.NewRow();
                  r["id"] = i;
                  r["name"] = name[counter];
                  t.Rows.Add(r);    
                  counter += 1;
              }
              return t;
          }
      

      感谢 cmets :D 随时欢迎您宝贵的 cmets

      【讨论】:

        猜你喜欢
        • 2021-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多