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

如何通过LINQ将含嵌套statement的SP800-53 XML加载到DataTable

解决方案

问题分析

你的代码存在两个核心问题:

  1. 命名空间处理缺失:XML里的family、statement等元素属于默认命名空间http://scap.nist.gov/schema/sp800-53/2.0,直接用Element("family")会找不到元素。
  2. 父级字段获取错误:嵌套的statement的父节点还是statement,不是control,用i?.Parent?.Element("family")只能拿到最外层statement的父级数据,深层statement会获取到null。

修正后的代码

// 定义两个命名空间:controls前缀的feed命名空间,以及默认的sp800-53核心命名空间
XNamespace controlsNs = "http://scap.nist.gov/schema/sp800-53/feed/2.0";
XNamespace defaultNs = "http://scap.nist.gov/schema/sp800-53/2.0";

XDocument xdoc = XDocument.Load("80053.xml");

// 先遍历每个control节点,再提取该control下所有嵌套的statement
var ccidata = xdoc.Descendants(controlsNs + "control")
    .SelectMany(control => 
        control.Descendants(defaultNs + "statement")
            .Select(statement => new 
            {
                // 从当前control节点获取父级字段
                Family = control.Element(defaultNs + "family")?.Value,
                ControlNumber = control.Element(defaultNs + "number")?.Value,
                Title = control.Element(defaultNs + "title")?.Value,
                // 从当前statement节点获取自身字段
                StatementNumber = statement.Element(defaultNs + "number")?.Value,
                Description = statement.Element(defaultNs + "description")?.Value
            })
    )
    // 过滤掉没有statement编号的空节点(比如最外层的空statement)
    .Where(item => !string.IsNullOrEmpty(item.StatementNumber))
    .ToList();

// 将数据转换为DataTable
DataTable dt = new DataTable();
dt.Columns.Add("Family", typeof(string));
dt.Columns.Add("ControlNumber", typeof(string));
dt.Columns.Add("Title", typeof(string));
dt.Columns.Add("StatementNumber", typeof(string));
dt.Columns.Add("Description", typeof(string));

foreach (var item in ccidata)
{
    dt.Rows.Add(
        item.Family,
        item.ControlNumber,
        item.Title,
        item.StatementNumber,
        item.Description
    );
}

代码说明

  • 命名空间处理:明确指定两个命名空间,确保能正确定位XML中的元素。
  • SelectMany的使用:先遍历每个control,再将每个control下的所有statement展开为扁平的集合,这样每个statement都能关联到所属的control字段。
  • 过滤空节点:最外层的statement没有number字段,通过Where过滤掉这类无效数据。
  • DataTable转换:直接遍历集合,将每个对象的属性值添加到DataTable的行中。

内容的提问来源于stack exchange,提问作者Fisher8370

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:48:21