2016-08-27 26 views
2

以下のXMLコードでoperating-system属性の値を取得しようとしていますが、これまでにstack、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> 

私は多くの方法を試してみましたが、ここで、最後の2つですしました:

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

ここではMicrosoftチュートリアルのこのメソッドを使用していますが、true/falseを返すだけで、値を割り当てるように操作することはできませんMicrosoft Windows 7 Enterprise Service Pack 1からosまでです。

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", 
        }; 

私は、上記のようなwhere句で様々な他のLINQからXMLへのクエリを使用してみましたが、それらはすべてNullまたはno 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 

あなたがあなたのXML名前空間を定義していても、あなたの要素のどれもがそれを使用しないことを実際に見ることができますhereそれにもう少し読みます。定義した名前空間(xmlns:cm)は、接頭辞cm:の要素にのみ適用され、それらの要素はそれらの要素ではありません。

:上記のコードは nullを返し、あなたが記述する必要があります

<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> 

このようなものです:

は、私は、次のようにXMLを変更した場合(名前空間のみのため xmlnsない xmlns:cmがある)ことを参照してください。
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; 
関連する問題