XSLT - XPath,某种类型的最深层元素

时间:2013-02-13 09:55:03

标签: xslt xpath

我试图找出一种确保感兴趣的元素不会(递归地)包含“相同”元素的方法。 E.g:

<Ev>
   <Ev attr="0">
      <Ev someOtherAttr="str1">
         <Ev attr="1">
            <Ev>
            </Ev>
         </Ev>
      </Ev>
   </Ev>
</Ev>

在这里,我想确保我所拥有的元素是具有名为attr的属性的最深元素(属性值可以是任意的,不应该匹配也不应该考虑)。

所以,在这种情况下,我想从两个“缩进”元素中选择<Ev attr="1">

<Ev attr="0"><Ev atttr="1">

我一直瞄准的目标:

<xsl:for-each select="//Ev/@attr">
    <xsl:if select="//*[not(child::Ev/@attr)]">
        <xsl:value-of select="count(ancestor::node())"/>
    </xsl:if>
</xsl:for-each>

但是 if 部分当然不是很好,或许每个select="<condition_a> and not(<condition_b>)"都可以去吗?

(用我尝试过的方式编辑了问题)

最诚挚的问候, 皮斯托尔先生

2 个答案:

答案 0 :(得分:2)

以下XPath表达式应该可以工作,尽管效率不高:

//Ev[@attr and not(.//Ev[@attr])]

答案 1 :(得分:1)

这样的事情会满足你的需求吗?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <xsl:apply-templates select="//Ev[@attr]" mode="deepest">
      <xsl:sort select="count(ancestor::*)" data-type="number" order="descending" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="Ev" mode="deepest">
    <xsl:if test="position() = 1">
      <!-- If we get to the inside of this xsl:if, the context node is 
           the deepest Ev in the selection -->
       <xsl:value-of select="count(ancestor::node())"/>          
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

在样本XML上运行时,会产生:

4