2016-08-27 208 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;