I'm trying to parse out information from a XCCDF output file but my Linq-to-Xml queries keep returning empty. Here are some of the ones I've tried to this point:
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());
}
I also tried:
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;
Here is a condensed version of the xccdf.xml file. Based on this version how would I get the title "Red Hat..." (line 5) and the title "daemon umask" (line 19)? (I do understand that my examples above do not attempt to get this data, I had to break it down to just trying to get anything...
<?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: [email protected].</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>
Both Benchmark
and title
have the namespace http://checklists.nist.gov/xccdf/1.1
, so you need to use this if you're going to query for title
.
Secondly, you parse using XElement.Parse
, so the result is an element representing the Benchmark
element. You then get its child elements (status
to Value
). Then you search for descendants of any of those called Benchmark
- you're not going to find any, as Benchmark
was where you started.
This should work:
var element = XElement.Load(s);
var findingDetails = new
{
title = (string)element.Element(ns + "title")
};
Alternatively, load as a document:
var doc = XDocument.Load(s);
var findingDetails =
from benchmark in doc.Descendants(ns + "Benchmark")
select new
{
title = (string)benchmark.Element(ns + "title")
};
Try following
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();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With