2012-09-21 74 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; 
     } 
    }