C# Linq-to-XML on XCCDF

本文关键字:XCCDF on Linq-to-XML | 更新日期: 2023-09-27 18:04:37

我试图从XCCDF输出文件中解析出信息,但我的Linq-to-Xml查询一直返回空。以下是我尝试过的一些方法:

XElement xelement = XElement.Load(s);
IEnumerable<XElement> findings = xelement.Elements();
XNamespace ns = "http://checklists.nist.gov/xccdf/1.1";
var findingDetails = from f in findings.Descendants(ns + "Benchmark")
                     select new
                     {
                         title = f.Element("title").Value            
                     };
foreach (var fd in findingDetails)
{
    Console.WriteLine(fd.ToString());
}

我也试过:

var findingDetails = from f in findings.Descendants(ns + "Benchmark")
                     select f;
var findingDetails = from f in findings.Descendants("Benchmark")
                     select new
                     {
                         title = f.Element("title").Value             
                     };
var findingDetails = from f in findings.Elements(ns + "Benchmark")
                     select new
                     {
                         title = f.Element("title").Value             
                     };
var findingDetails = from f in findings.Elements(ns + "Benchmark")
                     select f;

下面是xccdf.xml文件的压缩版本。基于这个版本,我怎么能得到标题"Red Hat…"(第5行)和标题"守护进程umask"(第19行)?(我明白我上面的例子并没有试图得到这些数据,我不得不把它分解成只是试图得到任何东西……)

<?xml version="1.0" encoding="UTF-8"?>
<cdf:Benchmark style="SCAP_1.1" resolved="1" id="RHEL_6_STIG" xsi:schemaLocation="http://checklists.nist.gov/xccdf/1.1 http://nvd.nist.gov/schema/xccdf-1.1.4.xsd http://cpe.mitre.org/dictionary/2.0 http://scap.nist.gov/schema/cpe/2.2/cpe-dictionary_2.2.xsd" xmlns:cdf="http://checklists.nist.gov/xccdf/1.1" xmlns:cpe="http://cpe.mitre.org/dictionary/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <cdf:status date="2016-04-22">accepted</cdf:status>
  <cdf:title>Red Hat Enterprise Linux 6 Security Technical Implementation Guide</cdf:title>
  <cdf:description>The Red Hat Enterprise Linux 6 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems.  Comments or proposed revisions to this document should be sent via e-mail to the following address: disa.stig_spt@mail.mil.</cdf:description>
  <cdf:notice id="terms-of-use"></cdf:notice>
  <cdf:reference href="http://iase.disa.mil">
        <dc:publisher>DISA</dc:publisher>
        <dc:source>STIG.DOD.MIL</dc:source>
  </cdf:reference>
  <cdf:plain-text id="release-info">Release: 11 Benchmark Date: 22 Apr 2016</cdf:plain-text>
  <cdf:platform idref="cpe:/o:redhat:enterprise_linux:6"></cdf:platform>
  <cdf:version>1</cdf:version>
  <cdf:Profile id="MAC-1_Classified">
        <cdf:title>I - Mission Critical Classified</cdf:title>            
  </cdf:Profile>
  <cdf:Value id="var_umask_for_daemons">
        <cdf:title>daemon umask</cdf:title>
        <cdf:description>Enter umask for daemons</cdf:description>
        <cdf:value>022</cdf:value>
        <cdf:value selector="022">022</cdf:value>
        <cdf:value selector="027">027</cdf:value>
  </cdf:Value>
</cdf:Benchmark>

C# Linq-to-XML on XCCDF

Benchmark title都有名称空间http://checklists.nist.gov/xccdf/1.1,所以如果您要查询title,则需要使用此名称空间。

其次,使用XElement.Parse进行解析,因此结果是一个表示Benchmark元素的元素。然后获得它的子元素(statusValue)。然后你搜索Benchmark的后代——你不会找到任何后代,因为Benchmark是你开始的地方。

这个应该可以工作:

var element = XElement.Load(s);
var findingDetails = new
{
    title = (string)element.Element(ns + "title")
};

或者,作为文档加载:

var doc = XDocument.Load(s);
var findingDetails =
    from benchmark in doc.Descendants(ns + "Benchmark")
    select new
    {
        title = (string)benchmark.Element(ns + "title")
    };

尝试以下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ProgrammingBasics
{
    class Exercise
    {
        const string FILENAME = @"c:'temp'test.xml";
        static void Main()
        {
            XDocument doc = XDocument.Load(FILENAME);
            var results = doc.Descendants().Where(x => x.Name.LocalName == "Benchmark").Select(y => new
            {
                title = (string)y.Elements().Where(z => z.Name.LocalName == "title").FirstOrDefault()
            }).FirstOrDefault();
        }
    }
}