2012-09-21 109 views
0

我正在解析一個XML文件並且硬編碼了一個方法來拆開一個字符串來創建一個多維數組。下面是我在解析XML的片段:將字符串轉換爲多維數組

<MeasPropList Path="userList" Type="System.Double[]"> 
    {1960, 1980, 0}, {1980, 0, 0}, {1960, 1980, 1990} 
</MeasPropList> 

的<MeasPropList>元素被用於任何類型的數據,而不只是數組或數字的。 這個XML在C#中的等價結果是:

double[,] userList = new[,] { { 1960.0, 1980.0, 0.0 }, 
         { 1980.0, 0.0, 0.0 }, 
         { 1960.0, 1980.0, 1990.0 } }; 

我就不告訴你我使用的代碼,它的工作原理確定,但我正在尋找一個更好的解決方案。
有沒有一種方法可以使用Array.ConvertAll <>?
是否有可用於解析XML數字數據的XML庫函數?

[編輯] 我發佈的代碼,我在這裏使用:
https://codereview.stackexchange.com/questions/15922/parsing-xml-to-create-ilist

+4

您應該從包含您當前使用的代碼開始。如果不知道現在在哪裏,我們無法知道它是否更好。哦,如果它有效,你應該改爲在codereview.stackexchange上發佈。 – Servy

+0

現在我無法想到現有的框架功能 - 但編寫基本的通用分析函數(String.Split和Convert)來處理這種情況應該相當簡單。 – Carsten

+0

基本拆分?存在問題,在{}和之間。邁克爾發佈一些代碼。 – Paparazzi

回答

0

如果你不固定在該格式,你可以使用鋸齒狀陣列和一個XmlSerializer:

double[][][] d = new double[][][] { new double[][] { 
              new double[] {1.0, 2.0, 3.0}, 
              new double[] {4.0, 5.0, 6.0}, 
              new double[] {7.0, 8.0, 9.0} 
             }, 
             new double[][] { 
              new double[] {10.0, 11.0, 12.0}, 
              new double[] {13.0, 14.0, 15.0}, 
              new double[] {16.0, 17.0, 18.0} 
             }, 
             new double[][] { 
              new double[] {19.0, 20.0, 21.0}, 
              new double[] {22.0, 23.0, 24.0}, 
              new double[] {25.0, 26.0 ,27.0} 
             } 
            }; 

    XmlSerializer x = new XmlSerializer(typeof(double[][][])); 

    using (StringWriter sw = new StringWriter()) 
    { 
     x.Serialize(sw, d); 
     Console.WriteLine(sw.ToString()); 
    } 

這產生了以下XML:

<?xml version="1.0" encoding="utf-16"?> 
<ArrayOfArrayOfArrayOfDouble xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <ArrayOfArrayOfDouble> 
    <ArrayOfDouble> 
     <double>1</double> 
     <double>2</double> 
     <double>3</double> 
    </ArrayOfDouble> 
    <ArrayOfDouble> 
     <double>4</double> 
     <double>5</double> 
     <double>6</double> 
    </ArrayOfDouble> 
    <ArrayOfDouble> 
     <double>7</double> 
     <double>8</double> 
     <double>9</double> 
    </ArrayOfDouble> 
    </ArrayOfArrayOfDouble> 
    <ArrayOfArrayOfDouble> 
    <ArrayOfDouble> 
     <double>10</double> 
     <double>11</double> 
     <double>12</double> 
    </ArrayOfDouble> 
    <ArrayOfDouble> 
     <double>13</double> 
     <double>14</double> 
     <double>15</double> 
    </ArrayOfDouble> 
    <ArrayOfDouble> 
     <double>16</double> 
     <double>17</double> 
     <double>18</double> 
    </ArrayOfDouble> 
    </ArrayOfArrayOfDouble> 
    <ArrayOfArrayOfDouble> 
    <ArrayOfDouble> 
     <double>19</double> 
     <double>20</double> 
     <double>21</double> 
    </ArrayOfDouble> 
    <ArrayOfDouble> 
     <double>22</double> 
     <double>23</double> 
     <double>24</double> 
    </ArrayOfDouble> 
    <ArrayOfDouble> 
     <double>25</double> 
     <double>26</double> 
     <double>27</double> 
    </ArrayOfDouble> 
    </ArrayOfArrayOfDouble> 
</ArrayOfArrayOfArrayOfDouble> 
+0

他想解析XML而不是創建它。 – Paparazzi

+0

@Blam我意識到這一點,但你也可以反序列化這只是通過調用反序列化,這就是爲什麼我建議不同的格式可能是一個選項。 – JamieSee

+0

好的,但> – Paparazzi

0

這裏是一個刺:

static void Main(string[] args) 
    { 
     var parser = new MeasPropListParser<double>(); 
     var values = parser.GetValues("{1960, 1980, 0}, {1980, 0, 0}, {1960, 1980, 1990}"); 
    } 


    public class MeasPropListParser<T> 
    { 
     private char[] comma = new char[] { ',' }; 
     private char[] rightBrace = new char[] { '}' }; 

     public T[,] GetValues(string input)   
     { 
      var dims = GetDimensions(input); 
      int rowCount = dims.Item1; 
      int colCount = dims.Item2; 

      T[,] array = new T[rowCount, colCount]; 
      var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)); 
      var rows = GetRows(input); 

      for (int x = 0; x < rowCount; x++) 
      { 
       var cols = new List<string>(rows[x].Split(comma, StringSplitOptions.RemoveEmptyEntries)); 
       for (int y = 0; y < colCount; y++) 
       { 
        array[x, y] = (T)converter.ConvertFromString(cols[y]); 
       } 

      } 

      return array; 
     } 

     private Tuple<int, int> GetDimensions(string input) 
     { 
      int rowCount = 0; 
      int colCount = 0; 
      foreach (var array in input.Trim().Split(rightBrace, StringSplitOptions.RemoveEmptyEntries)) 
      { 
       rowCount++; 
       if (colCount == 0) 
       { 
        colCount = array.Split(comma, StringSplitOptions.RemoveEmptyEntries).Length; 
       } 
      } 
      return new Tuple<int, int>(rowCount, colCount); 
     } 

     private List<string> GetRows(string input) 
     { 
      var list = new List<string>(); 
      foreach (var array in input.Trim().Split(rightBrace, StringSplitOptions.RemoveEmptyEntries)) 
      { 
       list.Add(array.Replace("{", "").Trim()); 
      } 
      return list; 
     } 
    }