2016-03-29 182 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; 
        } 

       } 
      } 
     } 
    } 

}