2014-06-11 181 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

相关问题