如何获取父元素的位置 - XSL

时间:2010-04-02 16:00:11

标签: xml xslt

我希望在xsl中可以做的是以下内容,但不幸的是父/位置()无效。

XSL

<xsl:template match="li">
  <bullet>
    <xsl:apply-templates/>
  </bullet>
  <!-- if this is the last bullet AND there are no more "p" tags, output footer -->
  <xsl:if test="count(ancestor::div/*) = parent/position()">
    <footer/>
  </xsl:if>
</xsl:template>

XML

<html>
  <div>
    <p>There is an x number of me</p>
    <p>There is an x number of me</p>
    <p>There is an x number of me</p>
    <ul>
      <li>list item</li>
      <li>list item</li>
      <li>list item</li>
      <li>list item</li>
      <li>list item</li>
    </ul>
  </div>
</html>

任何人都有任何想法如何从 WITHIN 我的模板匹配来解决这个问题?

谢谢!

4 个答案:

答案 0 :(得分:5)

您可以通过计算其前面的兄弟节点来查找源节点中父节点的位置:

<xsl:variable name="parent-position" 
              select="count(../preceding-sibling::*) + 1"/>

如果您想确定父p元素后面是否有ul元素,您可以在不使用职位的情况下对其进行测试:

<xsl:if test="../following-sibling:p">...</xsl:test>

然而,正如Dimitre和Oliver所指出的那样,在处理父元素时添加页脚更符合XSLT的精神。此外,显示的XPath表达式仅关注原始源树中的顺序。如果您打算在处理之前过滤元素或使用xsl:sort重新排序,这些路径将无法按预期工作,因为它们将查看原始排序并包括源树中的所有节点。

答案 1 :(得分:2)

在XSLT中执行此操作的好方法是

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

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="div">
  <xsl:apply-templates/>
  <footer/>
 </xsl:template>

 <xsl:template match="li">
  <bullet>
    <xsl:apply-templates/>
  </bullet>
 </xsl:template>
</xsl:stylesheet>

<footer/>的匹配在匹配div 的模板末尾最为自然,并且无需尝试比较任何位置。

答案 2 :(得分:1)

试试这个:

<xsl:template match="li">
  <bullet>
    <xsl:apply-templates/>
  </bullet>
  <xsl:if test="position()=last() and not(../following-sibling::p)">
    <footer/>
  </xsl:if>
</xsl:template>

答案 3 :(得分:0)

如果我理解正确,你正在寻找最后的li;这是一个li,后面没有li个元素。这可以这样测试:

<xsl:template match="li">
  <bullet>
    <xsl:apply-templates/>
  </bullet>
  <xsl:if test="not(following-sibling::li)">
    <footer />
  </xsl:if>
</xsl:template>

虽然在你给出它的情况下,在处理ul的结尾时添加页脚似乎更符合XSLT的精神:

<xsl:template match="ul">
  <ul>
    <xsl:apply-templates/>
  </ul>
  <footer />
</xsl:template>

<xsl:template match="li">
  <bullet>
    <xsl:apply-templates/>
  </bullet>
</xsl:template>