使用XPath和XSLT检查任何级别的父节点

时间:2014-12-05 14:34:40

标签: xslt xpath

我已经搜索过,但可能因为我不知道要搜索什么而错过了一些明显的东西。我发现很难将我的问题解释为一个简单的问题,所以让我解释一下:我使用以下代码(XSLT 1.0和XPath)来检查此节点的父节点是否属于最后一个祖父节点:

<xsl:when test="count(parent::*/preceding-sibling::*)+1 = count(parent::*/parent::*/*)">

它的工作原理与我想要的完全一样。我想要的是以一种或另一种方式使其更通用,使其与更多父节点一起工作。我可以添加另一个模板匹配并添加另一个测试:

<xsl:when test ="count(parent::*/parent::*/preceding-sibling::*)+1 = count(parent::*/parent::*/*)">

有没有办法在递归模板循环中添加“parent :: * /”而不是创建大量特定模板匹配?或者我应该完全找出更好的XPath代码?

请注意:我想检查每个级别的父节点。父母是父母的最后一位,父母是最后一位的父母,等等。

为了清楚起见,我这样使用它:

<xsl:choose>
  <xsl:when test="count(parent::*/preceding-sibling::*)+1 = count(parent::*/parent::*/*)">
    <!-- show image A -->
  </xsl:when>
  <xsl:otherwise>
    <!-- show image B -->
  </xsl:otherwise>
</xsl:choose>

1 个答案:

答案 0 :(得分:3)

<xsl:when test="count(parent::*/preceding-sibling::*)+1 = count(parent::*/parent::*/*)">

可以简化为:

<xsl:when test="not(../following-sibling::*)">

简单的英语&#34;我的父母没有以下元素兄弟&#34;


这很容易修改为:

<xsl:when test="not(../../following-sibling::*)">

简单的英语&#34;我父母的父母没有以下元素兄弟&#34; 。等


同时检查所有祖先:

<xsl:when test="not(ancestor::*/following-sibling::*)">

简单的英语&#34;我的祖先都没有以下元素兄弟&#34;


同时检查父母和祖父母:

<xsl:when test="not(ancestor::*[position() &lt;= 2]/following-sibling::*)">

用简单的英语&#34;我最近的两个祖先中没有一个拥有以下元素兄弟&#34;


编辑要单独检查所有祖先,请使用递归模板(优点:内部<xsl:apply-templates>的位置决定您是否有效地上升或下移祖先列表):< / p>

<xsl:template match="*" mode="line-img">
  <xsl:if test="following-sibling::*">
    <!-- show image A -->
  </xsl:if>
  <xsl:if test="not(following-sibling::*)">
    <!-- show image B -->
  </xsl:if>
  <xsl:apply-templates select=".." mode="line-img" />
</xsl:template>

<!-- and later... -->

<xsl:apply-templates select=".." mode="line-img" />

...或简单的for-each循环(始终按文档顺序工作):

<xsl:for-each select="ancestor::*">
  <xsl:if test="following-sibling::*">
    <!-- show image A -->
  </xsl:if>
  <xsl:if test="not(following-sibling::*)">
    <!-- show image B -->
  </xsl:if>
</xsl:for-each>

...或者,完全惯用(总是以文档顺序工作):

<xsl:template match="*" mode="line-img">
  <xsl:if test="following-sibling::*">
    <!-- show image A -->
  </xsl:if>
  <xsl:if test="not(following-sibling::*)">
    <!-- show image B -->
  </xsl:if>
</xsl:template>

<!-- and later... -->

<xsl:apply-templates select="ancestor::*" mode="line-img" />