2014-06-11 131 views
0

我試圖選擇使用root.SelectNodes()XPath的所有節點。有關參考,請參閱msdn-documentation使用xpath選擇具有屬性的所有節點

在說明的following文檔中,您還可以搜索包含屬性的節點(如果這實際上是錯誤的理解,請糾正我)。

所以我用下面的代碼行:

XmlNodeList nodes = projectDoc.DocumentElement.SelectNodes("descendant::Compile[attribute::Include]"); 

,我試圖閱讀以下數據:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> 
    <ItemGroup> 
     <Compile Include="ArrayExtensions.cs" /> 
     <Compile Include="ArrayIterator.cs" /> 
     <Compile Include="AutoInitializeAttribute.cs" /> 
     <Compile Include="AutoInitializePriority.cs" /> 
     <Compile Include="AutoRegisterAttribute.cs" /> 
     <Compile Include="FormattableExtensions.cs" /> 
     <Compile Include="Mathematics\PrimeNumbers.cs" /> 
    </ItemGroup> 
</Project> 

正如上面的代碼示例所示,我想所有包含Include-attribute的XmlNode。但是,當我執行我的代碼時,nodes包含0個元素。

我在這裏做錯了什麼?

+0

我強烈懷疑問題是命名空間 - 實際上您應該在'http:// schemas.microsoft.com/developer/msbuild/2003'命名空間中尋找'Compile'元素。是否有任何理由需要在XPath中執行此操作?使用LINQ to XML這將是微不足道的。 –

+0

沒有特別的理由不,如果你有更好的解決方案,將不勝感激!另外,我提供的問題的解決方案也很棒,僅用於學習目的。 – Matthijs

回答

1

我懷疑它失敗的原因與屬性部分無關 - 它根本找不到元素,因爲您只需要Compile元素,而實際上只有Compile元素位於命名空間中URI http://schemas.microsoft.com/developer/msbuild/2003

使用XPath執行此操作可能需要使用XmlNamespaceManager,然後您會將其傳入another overload of SelectNodes。個人而言,我會使用LINQ到XML代替,但:

XDocument doc = XDocument.Load("myfile.xml"); 
XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003"; 
var elements = doc.Descendants(ns + "Compile") 
        .Where(x => x.Attribute("Include") != null); 

在一般情況下,我找到的LINQ to XML比 「老」 XmlDocument基於API一個更簡潔的API。

+0

如何使用此計數?我在XDocument-API中看不到任何XNodeList(或類似)。我想說的是,這是什麼回報?元素列表還是? – Matthijs

+0

@Matthijs:它返回一個'IEnumerable '。您可以像使用其他序列一樣使用「Count()」擴展方法。如果你想要一個'List ',只需將一個調用添加到'.ToList()'。 –

+0

@John Skeet:完美的作品,謝謝! – Matthijs

相關問題