2

假设我有这个文件。

<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,CD. 但我不想要D,因为它嵌套在另一个“a:”元素中。

如果我说

A.SelectNodes( "//a:*[not(ancestor::a:*)]", namespaceManager )

当然,我什么也得不到,因为 A 和它的父级都在“a”命名空间中。

如何只选择Band C,即与命名空间匹配的最浅的孩子?

谢谢。

请注意,这是 XPath 1.0 (.NET 2),所以我不能使用范围内前缀(它看起来会有所帮助)。

此外,这并不是关于名称空间的真正问题。与其他匹配标准相同的困境。

4

3 回答 3

2

那这个呢:

<xsl:variable name="parents" select="ancestor-or-self::a:*" />
<xsl:value-of select="//a:*[not(deep-equal(ancestor::a:*, $parent))]" />

在 XSLT 中,这似乎很简单(将节点集存储为变量),但我不完全知道如何在 C# 中实现这一点。

编辑:进一步研究使用计数的想法,这可能可行:

int nrParents = A.SelectNodes("ancestor-or-self::a:*", namespaceManager).Count(); // Or was it Size?
A.SelectNodes("//a:*[count(ancestor::a:*)!=" + nrParents + "]", namespaceManager)
于 2010-06-03T22:09:38.613 回答
1

这不是一个 XSLT 问题,所以这里有一个 XPath 表达式,它选择想要的两个节点

/*/*/descendant::a:*[not(count(ancestor::a:*) > 2)]
于 2010-06-04T19:02:04.377 回答
0

这对于单个 XPath 1.0 表达式是不可行的。扩展使用 XSLT 的 Marc 的答案,您可以为 1.0 执行此操作:

<xsl:variable name="n" select="count(ancestor-or-self::a:*)" />
<xsl:variable name="result" select=".//a:*[count(ancestor::a:*) = $n]" />

或等效的 C# 调用序列Select...

于 2010-06-03T22:23:56.870 回答