代码之家  ›  专栏  ›  技术社区  ›  harpo

如何选择具有xpath的最浅匹配元素?

  •  2
  • harpo  · 技术社区  · 14 年前

    假设我有这个文件。

    <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”名称空间中。

    我怎样才能选择 C 也就是说,与命名空间匹配的最浅子级?

    谢谢。

    注意,这是xpath 1.0(.net 2),所以我不能在作用域内使用前缀(它看起来会有帮助)。

    另外,这实际上不是关于名称空间的问题。与其他匹配条件相同。

    3 回复  |  直到 14 年前
        1
  •  0
  •   Pavel Minaev    14 年前

    单用一个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... .

        2
  •  2
  •   Marc    14 年前

    这个怎么样:

    <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)
    
        3
  •  1
  •   Dimitre Novatchev    14 年前

    这不是一个XSLT问题,因此这里有一个选择所需两个节点的xpath表达式 :

    /*/*/descendant::a:*[not(count(ancestor::a:*) > 2)]
    
    推荐文章