XSL(T)当前/上一个/下一个

时间:2009-07-15 15:42:30

标签: xslt

我知道有current()函数来检索XSL中的当前节点,但是有没有办法能够引用“previous”和“next”节点来引用当前位置?

3 个答案:

答案 0 :(得分:4)

没有。当前上下文无法知道哪些节点是“下一个”或“上一个”。

这是因为,例如,当应用模板时,机制就像这样:

  1. 你这样做:<xsl:apply-templates select="*" /><!-- select 3 nodes (a,b,c) -->
  2. XSLT处理器生成要处理的节点列表(a,b,c)
  3. 对于每个节点,XSLT处理器选择并执行匹配模板
  4. 调用模板时,定义了current()节点,并定义了position(),但模板不知道执行流程。
  5. 只要结果保证相同,执行顺序就受处理者偏好的影响。您的(理论上)预测对于一个处理器可能是正确的,对另一个处理器则是错误的。对于像XSLT这样的无副作用的编程语言,我认为这样的知识会是一件危险的事情(因为人们会开始依赖执行顺序)。
  6. 您可以使用following::siblingpreceding::sibling XPath轴,但这与确定下一步将处理哪个节点不同

    修改

    以上解释试图回答问题,因为OP 意味着不同的东西。它只是关于分组/输出唯一节点。

    根据OP的要求,这里快速演示如何使用XPath轴实现分组。

    XML(项目已预先排序):

    <items>
      <item type="a"></item>
      <item type="a"></item>
      <item type="a"></item>
      <item type="a"></item>
      <item type="b"></item>
      <item type="e"></item>
    </items>
    

    XSLT

    <xsl:stylesheet 
      version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >
    
      <xsl:template match="/items">
        <!-- copy the root element -->
        <xsl:copy>
          <!-- select those items that differ from any of their predecessors -->
          <xsl:apply-templates select="
            item[
              not(@type = preceding-sibling::item/@type)
            ]
          " />
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="item">
        <!-- copy the item to the output -->
        <xsl:copy-of select="." />
      </xsl:template>
    
    </xsl:stylesheet>
    

    输出:

    <items>
      <item type="a"></item>
      <item type="b"></item>
      <item type="e"></item>
    </items>
    

答案 1 :(得分:1)

假设您正在讨论文档结构中的下一个和上一个节点,而不是当前的执行流(例如for-each循环),请参阅preceding-siblingfollowing-sibling轴:XPath Axes on W3

获取同名的下一个节点:

following-sibling::*[name() = name(current())]

根据具体情况,您可能需要在第一部分中使用name(.)

答案 2 :(得分:0)

您可以跟踪变量中的上一个和当前值,以便以后处理。 即你可以保留标签(i-2),标签(i-1)并在标签(i)中使用它们。

只是另一个想法。

问候。