You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将XSLT生成的XML转换为结构化数据表并实现反向还原?

如何将XSLT生成的XML转换为结构化数据表并实现反向还原?

我明白你现在的困扰——把这种嵌套结构的XML转成规整的DataTables确实容易摸不着头绪,尤其是它还来自4张原始表的XSLT转换结果。咱们一步步来拆解解决:

一、把现有XML解析为结构化DataTables

你的XML里有三种典型结构,咱们分别处理:

1. 单条记录型(如TableName0)

这种是单个<obj>节点对应一张表的单行数据,子节点的name属性是列名,val属性是值。直接遍历子节点生成列和行即可:

// 加载XML文档
XmlDocument doc = new XmlDocument();
doc.Load("your-target.xml");

// 处理TableName0
XmlNode table0Node = doc.SelectSingleNode("//obj[@name='TableName0']");
DataTable table0 = new DataTable("TableName0");

// 先添加所有列
foreach (XmlNode fieldNode in table0Node.ChildNodes)
{
    string colName = fieldNode.Attributes["name"].Value;
    // 根据节点类型(int/str)指定列的数据类型
    Type colType = fieldNode.Name == "int" ? typeof(int) : typeof(string);
    table0.Columns.Add(colName, colType);
}

// 填充单行数据
DataRow row0 = table0.NewRow();
foreach (XmlNode fieldNode in table0Node.ChildNodes)
{
    string colName = fieldNode.Attributes["name"].Value;
    string val = fieldNode.Attributes["val"].Value;
    row0[colName] = fieldNode.Name == "int" ? int.Parse(val) : val;
}
table0.Rows.Add(row0);

2. 多行对象型(如TableName1)

外层<list>对应表,内部每个<obj>是一行数据,注意不同行可能有不同的列(比如RowOfData2比RowOfData1多3列),所以要先收集所有可能的列名,再逐行填充:

// 处理TableName1
XmlNodeList table1Objs = doc.SelectNodes("//list[@name='TableName1']/obj");
DataTable table1 = new DataTable("TableName1");
HashSet<string> allColNames = new HashSet<string>();

// 第一步:遍历所有行,收集完整的列名集合
foreach (XmlNode objNode in table1Objs)
{
    foreach (XmlNode fieldNode in objNode.ChildNodes)
    {
        allColNames.Add(fieldNode.Attributes["name"].Value);
    }
}

// 添加所有列到DataTable(这里先统一用string类型,你可以根据实际节点类型调整)
foreach (string colName in allColNames)
{
    table1.Columns.Add(colName);
}

// 第二步:逐行填充数据
foreach (XmlNode objNode in table1Objs)
{
    DataRow row = table1.NewRow();
    foreach (XmlNode fieldNode in objNode.ChildNodes)
    {
        string colName = fieldNode.Attributes["name"].Value;
        // 处理<int>/<str>的val属性,以及<ref>的href属性
        string val = fieldNode.Attributes["val"]?.Value ?? fieldNode.Attributes["href"]?.Value;
        row[colName] = val;
    }
    table1.Rows.Add(row);
}

3. 嵌套列表型(如TableName2)

外层<list>是表,内层<list>是行,行内的<int>节点是列(name属性为列名),同样先收集列名再填充:

// 处理TableName2
XmlNodeList table2Rows = doc.SelectNodes("//list[@name='TableName2']/list");
DataTable table2 = new DataTable("TableName2");
HashSet<string> table2ColNames = new HashSet<string>();

// 收集所有列名
foreach (XmlNode rowNode in table2Rows)
{
    foreach (XmlNode fieldNode in rowNode.ChildNodes)
    {
        table2ColNames.Add(fieldNode.Attributes["name"].Value);
    }
}

// 添加列(这里都是int类型,可根据实际调整)
foreach (string colName in table2ColNames)
{
    table2.Columns.Add(colName, typeof(int));
}

// 填充每一行数据
foreach (XmlNode rowNode in table2Rows)
{
    DataRow row = table2.NewRow();
    foreach (XmlNode fieldNode in rowNode.ChildNodes)
    {
        string colName = fieldNode.Attributes["name"].Value;
        int val = int.Parse(fieldNode.Attributes["val"].Value);
        row[colName] = val;
    }
    table2.Rows.Add(row);
}

二、反向还原:从XML转回原始4张数据表

这里要明确一个关键点:XSLT是单向转换工具,它只能把原始XML/数据表转成你现在拿到的XML,没法自动反向转换。不过有几个可行的思路:

  • 写反向XSLT:如果原XSLT的转换逻辑很清晰(比如只是把原始表的字段映射成当前的<obj>/<list>结构),你可以编写一个反向的XSLT,把当前的XML转换回原始数据表的XML结构,然后再导入DataSet生成原始表。
  • 手动映射结构:如果你能拿到原始4张表的结构定义(列名、数据类型、关联关系),可以直接基于当前XML的内容,按照对应关系把数据填充到原始结构的DataTables里——逻辑和前面解析XML的思路类似,只是列名和结构要对应原始表。
  • 利用原XSLT的映射信息:如果原XSLT里保留了字段的原始映射(比如注释或者特殊属性),那反向会更简单,但从你给出的XML来看没有这类信息,所以得靠人工梳理结构对应关系。

总的来说,先根据XML的三种结构分别解析成规整的DataTables;反向还原的核心是还原原始表的结构映射,要么写反向XSLT,要么手动对应填充。

备注:内容来源于stack exchange,提问作者Jason Shoulders

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 15:22:40