[英]XML Linq with nested elements
我正在尝试将格式如下的 XML 文件加载到数据表中:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<controls:controls xmlns="http://scap.nist.gov/schema/sp800-53/2.0"
xmlns:controls="http://scap.nist.gov/schema/sp800-53/feed/2.0"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
pub_date="2017-08-01"
xsi:schemaLocation="http://scap.nist.gov/schema/sp800-53/feed/2.0 http://scap.nist.gov/schema/sp800-53/feed/2.0/sp800-53-feed_2.0.xsd">
<controls:control>
<family>ACCESS CONTROL</family>
<number>AC-1</number>
<title>POLICY AND PROCEDURES</title>
<baseline>LOW</baseline>
<baseline>MODERATE</baseline>
<baseline>HIGH</baseline>
<baseline>PRIVACY</baseline>
<statement>
<description/>
<statement>
<number>AC-1a.</number>
<description>Develop, document, and disseminate to [Assignment: organization-defined personnel or roles]:</description>
<statement>
<number>AC-1a.1.</number>
<description>[Selection (one or more): Organization-level; Mission/business process-level; System-level] access control policy that:</description>
<statement>
<number>AC-1a.1.(a)</number>
<description>Addresses purpose, scope, roles, responsibilities, management commitment, coordination among organizational entities, and compliance; and</description>
</statement>
<statement>
<number>AC-1a.1.(b)</number>
<description>Is consistent with applicable laws, executive orders, directives, regulations, policies, standards, and guidelines; and</description>
</statement>
</statement>
<statement>
<number>AC-1a.2.</number>
<description>Procedures to facilitate the implementation of the access control policy and the associated access controls;</description>
</statement>
</statement>
<statement>
<number>AC-1b.</number>
<description>Designate an [Assignment: organization-defined official] to manage the development, documentation, and dissemination of the access control policy and procedures; and</description>
</statement>
<statement>
<number>AC-1c.</number>
<description>Review and update the current access control:</description>
<statement>
<number>AC-1c.1.</number>
<description>Policy [Assignment: organization-defined frequency] and following [Assignment: organization-defined events]; and</description>
</statement>
<statement>
<number>AC-1c.2.</number>
<description>Procedures [Assignment: organization-defined frequency] and following [Assignment: organization-defined events].</description>
</statement>
</statement>
</statement>
</controls:control>
我能够提取家庭和其他价值观,但是当我尝试访问这些陈述时,我什么也得不到。 我需要创建一个表,其中包含一行中的每个语句值以及行中的父值(如家庭和标题)。
这是我得到的:
string ns = "http://scap.nist.gov/schema/sp800-53/feed/2.0";
XDocument xdoc = XDocument.Load("80053.xml");
var ccidata = xdoc.Descendants(XName.Get("control", ns))
.Descendants("statement")
.Select(i => new
{
family = i?.Parent?.Element("family")?.Value,
number = i?.Element("number")?.Value,
}).ToList();
我会很感激任何指导。
我更喜欢使用 Xml Linq (XDocument)。 您缺少名称空间。 请参见下面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication23
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
List<Ccidata> ccidata = Ccidata.GetData(FILENAME);
}
}
public class Ccidata
{
public string description { get; set; }
public string number { get; set; }
public static List<Ccidata> GetData(string filename)
{
XDocument doc = XDocument.Load(filename);
XElement control = doc.Root;
XNamespace ns = control.GetDefaultNamespace();
XNamespace nsControl = control.GetNamespaceOfPrefix("controls");
List<Ccidata> ccidata = doc.Descendants(ns + "statement")
.Select(x => new Ccidata() { description = (string)x.Element(ns + "description"), number = (string)x.Element(ns + "number") }).ToList();
//add root number
ccidata[0].number = (string)doc.Descendants(nsControl + "control").First().Element(ns + "number");
return ccidata;
}
}
}
我认为使用XPath会有更好的运气。 尝试这个:
// very crude resolver but should give you what's needed in this example
class ControlsResolver : IXmlNamespaceResolver
{
public IDictionary<string, string> GetNamespacesInScope(XmlNamespaceScope scope)
{
return new Dictionary<string, string>() { { "controls", "http://scap.nist.gov/schema/sp800-53/feed/2.0" } };
}
public string LookupNamespace(string prefix)
{
return "http://scap.nist.gov/schema/sp800-53/feed/2.0";
}
public string LookupPrefix(string namespaceName)
{
return "controls";
}
}
//
//
//
var resolver = new ControlsResolver();
//this will give you all <controls:control> elements
var controlList = xdoc.XPathSelectElements("//controls:control", resolver);
//this just gets the children of the first one
var children = ele.First().Nodes();
// this gets any statements that are direct descendants but you'll have to iterate through them to find the other descendants
var statement = children.Where(n => ((XElement)n).Name.LocalName == "statement").ToList()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.