2016-08-27 169 views
2

我试图在下面的xml代码中获得operating-system属性的值,但是在我尝试从堆栈,dotnetcurry和Microsoft获得的所有解决方案中,我都获得了一个NullPointerExecption或它只是没有返回任何值。C#按属性名称获取Xelement属性值

这里是我试图解析XML数据:

<Report name="Black Workstation" xmlns:cm="http://www.nessus.org/cm"> 
    <ReportHost name="192.168.1.000> 
    <HostProperties> 
     <tag name="HOST_END">Wed Jun 29 10:32:54 2016</tag> 
     <tag name="LastAuthenticatedResults">1467214374</tag> 
     <tag name="patch-summary-total-cves">5</tag> 
     <tag name="cpe">cpe:/o:microsoft:windows</tag> 
     <tag name="operating-system">Microsoft Windows 7 Enterprise Service Pack 1</tag> 
    </HostProperties> 
    </ReportHost> 
</Report> 

我已经试过许多方法,但这里是最后两个:

XNamespace ns = "http://www.nessus.org/cm"; 
var operatingSystem = (findings.Where(a => a.Attribute("name").Value == "operating-system") 
.Select(a => a.Value));           

var operatingSystem = findings.Descendants().Where(x => x.Attribute("name").Value == ns + "operating-system"); 

也试过这个解决方案:Use Linq to Xml with Xml namespaces

我在这里有微软教程的这个方法,但它只返回true/false,我不能操纵它,因此它分配值Microsoft Windows 7 Enterprise Service Pack 1os变量。

XElement xelement = XElement.Load(s); 
IEnumerable<XElement> findings = xelement.Elements(); 

var hostProperties = from hp in findings.Descendants("HostProperties") 
        select new 
        { 
         os = (string)hp.Element("tag").Attribute("name").Value == "operating-system", 
        }; 

我一直利用各种其他的LINQ到XML查询与where条款像上面尝试,但他们都返回Nullno values to enumerate

+1

顺便说一句 - 这个问题真的很好。给相关的数据来尝试一下,你没有得到什么,你也试过:)随着时间的推移:) –

回答

3

在你的情况,你不需要应用了命名空间:

var result = XDocument.Load("data.xml") 
         .Descendants("tag") 
         .Where(e => e.Attribute("name").Value == "operating-system") 
         .FirstOrDefault()?.Value; 

//result = Microsoft Windows 7 Enterprise Service Pack 1 

读多一点进去here你可以看到,即使你在你的XML不关你的元素定义命名空间使用。您定义的名称空间(xmlns:cm)仅适用于使用cm:前缀的元素,而它们不属于它们。

看到,如果我改变你的XML如下空间(namespace仅供xmlns而不是xmlns:cm):

<Report name="Black Workstation" xmlns="http://www.nessus.org/cm"> 
    <ReportHost name="192.168.1.000"> 
    <HostProperties> 
    <tag name="HOST_END">Wed Jun 29 10:32:54 2016</tag> 
    <tag name="LastAuthenticatedResults">1467214374</tag> 
    <tag name="patch-summary-total-cves">5</tag> 
    <tag name="cpe">cpe:/o:microsoft:windows</tag> 
    <tag name="operating-system">Microsoft Windows 7 Enterprise Service Pack 1</tag> 
    </HostProperties> 
</ReportHost> 
</Report> 

上面的代码将返回null,你将不得不写的是这样的:

XNamespace ns = "http://www.nessus.org/cm"; 
var result = XDocument.Load("data.xml") 
         .Descendants(ns + "tag") 
         .Where(e => e.Attribute("name").Value == "operating-system") 
         .FirstOrDefault()?.Value; 
+0

感谢您的时间和帮助 – Chris

+0

@Chris - 你是非常欢迎:) –

+0

有没有另一种方式没有'FirstorDefault()'做?不管它是否是第一次,它在哪里选择什么? – Chris

0

请尝试以下

XDocument document = XDocument.Load("content.xml"); 
var name = document.XPathSelectElement("Report/ReportHost/HostProperties/tag[@name='operating-system']").Value;