2

我有一个具有以下结构的 XML 文件:

<InterfaceLimits day="2012-08-22" xmlns="http://someurl.com/xml">
  <InterfaceLimitsHourly hour="1">
    <InterfaceLimit>
      <InterfaceLimitName>NAME1</InterfaceLimitName>
      <FlowMW>3684</FlowMW>
      <LimitMW>5100</LimitMW>
    </InterfaceLimit>
    <InterfaceLimit>
      <InterfaceLimitName>NAME2</InterfaceLimitName>
      <FlowMW>3310</FlowMW>
      <LimitMW>5900</LimitMW>
    </InterfaceLimit>
  </InterfaceLimitsHourly>
  <InterfaceLimitsHourly hour="2">
  ... etc.
</InterfaceLimits>

当我将此数据导入 Excel 时,我得到以下漂亮、整洁的表:

day        hour  InterfaceLimitName   FlowMW  LimitMW
8/22/2012  1     NAME1                3684    5100
8/22/2012  1     NAME2                3310    5900
... etc.

但是,当我使用以下方法将 XML 文件导入 .NET 中的 DataSet 时,我得到以下多个表:

   day
0  2012-08-22

   hour
0  1
1  2
2  3
3  4
4  5
5  6
6  7
... etc.

   InterfaceLimitName  FlowMW  LimitMW
0  NAME1               3684    5100
1  NAME2               3310    5900
... etc.

我用来导入文件的代码片段如下:

_sourceDS.ReadXml(_downloadFile, XmlReadMode.Auto)

其中 _sourceDS 是一个空的 DataSet,_downloadFile 是一个字符串,其中包含下载的 XML 文件的完整路径。

有什么想法可以(半自动且不提前知道结构)强制导入到 Excel 中的单个表中吗?

4

1 回答 1

1

DataSet始终从您的 XML 创建三个表。

您可以尝试将其加载到 aDataTable中,但是您必须提供一个模式,虽然我不知道它是否真的可以工作,但它可能不是您想要的。

因此,唯一的解决方案是将您合并DataSet到一个DataTable.


结果将如下所示:

在此处输入图像描述

当心,一大堆代码(但翻译成 VB.Net 取决于你):

public static DataTable Flatten(DataSet dataSet)
{

    foreach (DataTable table in dataSet.Tables)
        foreach (DataColumn column in table.Columns)
            if (!column.ColumnName.Contains("_Id")) column.ColumnName = table.TableName + "." + column.ColumnName;

    DataTable resultTable = dataSet.Tables[dataSet.Relations[0].ChildTable.TableName];
    foreach (DataRelation relation in dataSet.Relations)
        resultTable = Join(dataSet.Tables[relation.ParentTable.TableName], resultTable, relation.ParentColumns[0].ColumnName, relation.ChildColumns[0].ColumnName);

    return resultTable;
}

public static DataTable Join (DataTable first, DataTable second, string firstJoinColumn, string secondJoinColumn) 
{ 
    return Join(first, second, new DataColumn[]{first.Columns[firstJoinColumn]}, new DataColumn[]{first.Columns[secondJoinColumn]}); 
} 

public static DataTable Join(DataTable first, DataTable second, DataColumn[] firstJoinColumn, DataColumn[] secondJoinColumn)
{
    DataTable table = new DataTable("Join");
    using (DataSet ds = new DataSet())
    {
        ds.Tables.AddRange(new DataTable[] { first.Copy(), second.Copy() });

        DataColumn[] parentcolumns = new DataColumn[firstJoinColumn.Length];
        for (int i = 0; i < parentcolumns.Length; i++)
            parentcolumns[i] = ds.Tables[0].Columns[firstJoinColumn[i].ColumnName];

        DataColumn[] childcolumns = new DataColumn[secondJoinColumn.Length];
        for (int i = 0; i < childcolumns.Length; i++)
            childcolumns[i] = ds.Tables[1].Columns[secondJoinColumn[i].ColumnName];

        DataRelation r = new DataRelation(string.Empty, parentcolumns, childcolumns, false);
        ds.Relations.Add(r);

        for (int i = 0; i < first.Columns.Count; i++)
            table.Columns.Add(first.Columns[i].ColumnName, first.Columns[i].DataType);

        for (int i = 0; i < second.Columns.Count; i++)
            if (!table.Columns.Contains(second.Columns[i].ColumnName))
                table.Columns.Add(second.Columns[i].ColumnName, second.Columns[i].DataType);
            else
                table.Columns.Add(second.Columns[i].ColumnName + "_Second", second.Columns[i].DataType);

        table.BeginLoadData();

        foreach (DataRow firstrow in ds.Tables[0].Rows)
        {
            DataRow[] childrows = firstrow.GetChildRows(r);
            if (childrows != null && childrows.Length > 0)
            {
                object[] parentarray = firstrow.ItemArray;
                foreach (DataRow secondrow in childrows)
                {
                    object[] secondarray = secondrow.ItemArray;
                    object[] joinarray = new object[parentarray.Length + secondarray.Length];
                    Array.Copy(parentarray, 0, joinarray, 0, parentarray.Length);
                    Array.Copy(secondarray, 0, joinarray, parentarray.Length, secondarray.Length);
                    table.LoadDataRow(joinarray, true);
                }
            }
            else
            {
                object[] parentarray = firstrow.ItemArray;
                object[] joinarray = new object[parentarray.Length];
                Array.Copy(parentarray, 0, joinarray, 0, parentarray.Length);
                table.LoadDataRow(joinarray, true);
            }
        }
        table.EndLoadData();
    }
}

资料来源:RedAnt 科技博客weblogs.sqlteam.com

于 2012-08-30T13:44:30.770 回答