2016-03-29 26 views
0

我有下面的XML:根据 “史记”解析XML数据表到

<RECORDS> 
    <RECORD> 
    <PROPERTY NAME="FNAME" TYPE="string"></PROPERTY> 
    <PROPERTY NAME="LNAME" TYPE="string"> 
     <VALUE>SMITH</VALUE> 
    </PROPERTY> 
    <PROPERTY NAME="ZIP" TYPE="string"> 
     <VALUE></VALUE> 
    </PROPERTY> 
    <PROPERTY NAME="PHONE" TYPE="string"> 
     <VALUE>5551212</VALUE> 
    </PROPERTY> 
    </RECORD> 
    <RECORD> 
    .... 
    </RECORD> 
    <RECORD> 
    .... 
    </RECORD> 
    <RECORD> 
    .... 
    </RECORD> 
</RECORDS> 

有可能是1000 “RECORD” 的节点。我试图简单地将每个记录转储到一个数据行(或整个事物到一个数据表)。我很乐意将所有“VALUE”放入每一行的列中。有没有一种有效的方式在C#中执行此操作?做foreach()和每次访问每个属性似乎非常缓慢。

我想它会涉及Row.ItemArray或可能XMLArray或沿着这些线的东西。

有兴趣看到一个很好的解决方案!

+0

如果你想要去的数据集的路线,尝试:var数据=新的DataSet(); dataSet.ReadXml(xmlVariable); – mcr

+0

什么是“非常慢”?你从根本上必须迭代每条记录,将它从XML转换为数据行,所以'foreach'本身并不是问题。 –

+0

使用ReadXML可能会工作,但我不清楚如何告诉它的结构。如果您注意到,列名称是属性的属性,并且值是VALUE的InnerText(如果存在)。 –

回答

0

试试这个

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

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string xml = 
       "<RECORDS>" + 
        "<RECORD>" + 
        "<PROPERTY NAME=\"FNAME\" TYPE=\"string\"></PROPERTY>" + 
        "<PROPERTY NAME=\"LNAME\" TYPE=\"string\">" + 
         "<VALUE>SMITH</VALUE>" + 
        "</PROPERTY>" + 
        "<PROPERTY NAME=\"ZIP\" TYPE=\"string\">" + 
         "<VALUE></VALUE>" + 
        "</PROPERTY>" + 
        "<PROPERTY NAME=\"PHONE\" TYPE=\"string\">" + 
         "<VALUE>5551212</VALUE>" + 
        "</PROPERTY>" + 
        "</RECORD>" + 
       "</RECORDS>"; 

      XDocument doc = XDocument.Parse(xml); 

      DataTable dt = new DataTable(); 

      List<XElement> properties = doc.Descendants("PROPERTY").ToList(); 

      //add columns to table 
      foreach (XElement property in properties) 
      { 
       string name = property.Attribute("NAME").Value; 
       string _type = property.Attribute("TYPE").Value; 
       if(!dt.Columns.Contains(name)) 
       { 
        dt.Columns.Add(name, Type.GetType("System." + _type, false, true)); 
       } 
      } 

      //add rows to table 
      foreach(XElement record in doc.Descendants("RECORDS").ToList()) 
      { 
       DataRow newRow = dt.Rows.Add(); 
       foreach (XElement property in properties) 
       { 
        string name = property.Attribute("NAME").Value; 
        Type _type = Type.GetType("System." + property.Attribute("TYPE").Value, false, true); 
        string value = property.Value; 

        switch (_type.ToString()) 
        { 
         case "System.String" : 
          newRow[name] = (string)value; 
          break; 
         case "System.Int" : 
          newRow[name] = int.Parse(value); 
          break; 
        } 

       } 
      } 
     } 
    } 

}