假设我有这份文件。
<a:Root>
<a:A>
<title><a:B/></title>
<a:C>
<item><a:D/></item>
</a:C>
</a:A>
</a:Root>
我将XmlNode设置为<a:A>
元素。
如果我说
A.SelectNodes( "//a:*", namespaceManager )
我得到B
,C
和D
。但我不想要D
,因为它嵌套在另一个“a:”元素中。
如果我说
A.SelectNodes( "//a:*[not(ancestor::a:*)]", namespaceManager )
当然,我什么都没得到,因为A和它的父都在“a”命名空间中。
如何选择B
和C
,即与名称空间匹配的最浅的孩子?
感谢。
注意,这是XPath 1.0(.NET 2),因此我不能使用范围内前缀(它看起来会有所帮助)。
此外,这不是关于命名空间的问题。窘境与其他匹配标准相同。
答案 0 :(得分:2)
这个怎么样:
<xsl:variable name="parents" select="ancestor-or-self::a:*" />
<xsl:value-of select="//a:*[not(deep-equal(ancestor::a:*, $parent))]" />
在XSLT中,这似乎很简单(将节点集存储为变量),但我不知道如何在C#中实现它。
编辑:进一步研究使用count的想法,这可能有用:
int nrParents = A.SelectNodes("ancestor-or-self::a:*", namespaceManager).Count(); // Or was it Size?
A.SelectNodes("//a:*[count(ancestor::a:*)!=" + nrParents + "]", namespaceManager)
答案 1 :(得分:1)
这不是XSLT问题,所以这里有一个XPath表达式,用于选择想要的两个节点:
/*/*/descendant::a:*[not(count(ancestor::a:*) > 2)]
答案 2 :(得分:0)
单个XPath 1.0表达式无法做到这一点。扩展Marc使用XSLT的答案,你可以为1.0:
执行此操作<xsl:variable name="n" select="count(ancestor-or-self::a:*)" />
<xsl:variable name="result" select=".//a:*[count(ancestor::a:*) = $n]" />
或等效的C#调用Select...
。