XSLT position()值分别对应于已过滤的节点

时间:2013-08-16 11:52:41

标签: xml xslt saxon

关于我的question

position()函数返回整个文档中实际节点的位置,如何获取位置  关于所选节点。假设我有100个城市的列表,我根据给定的过滤器列表排除10(请参阅问题)现在我想根据所选节点而不是原始文档位置进行计数。

简单来说,这是一个计数器/增量问题,因为我看到计数器是不可能的。我们如何创建或使用现有函数来匹配position()以获取所选节点中节点的位置。

我希望我的问题很明确。

编辑示例场景

  <xsl:template match="/">
    <xsl:apply-templates select="db:databaseChangeLog/db:changeSet[*[1][($excludes eq '' or not(@tableName = tokenize($excludes, ',')))]]"/> 
  </xsl:template>

   <xsl:template match="db:changeSet">
      ...
   </xsl:template>

我根据子节点属性名称选择父节点。

2 个答案:

答案 0 :(得分:1)

您对position功能的描述错误。请参阅http://www.w3.org/TR/xslt20/#focus,特别是“上下文位置是当前正在处理的项目序列中的上下文项目的位置。只要上下文项目发生更改,它就会发生变化。当xsl:apply-templates或xsl等指令时: for-each用于处理项目序列,序列中的第一项处理的上下文位置为1,第二项目的上下文位置为2,依此类推。] XPath返回上下文位置表达位置()“。

例如,如果我们有<xsl:apply-templates select="cities/city[not(@abbr = $skip/abbr)]"/>并且我们在匹配position元素的模板中使用city函数,例如

<xsl:template match="city">
  <xsl:copy>
    <xsl:value-of select="position()"/>
  </xsl:copy>
</xsl:template>

我们将获得<city>1</city><city>2</city>等等。

答案 1 :(得分:1)

我认为最好使用xsl:number。使用xsl:number,您应该能够更轻松地排除元素。

以下是一个小例子,显示来自position()xsl:number的结果进行比较。

XML输入

<cities>
    <city>City One</city>
    <city>City Two</city>
    <city>City Three</city>
    <city>City Four</city>
    <city>City Five</city>
    <city>City Six</city>
    <city>City Seven</city>
    <city>City Eight</city>
    <city>City Nine</city>
    <city>City Ten</city>
</cities>

XSLT 2.0 (我认为2.0可以安全地假设,因为问题标记为saxon并且您在评论中使用了tokenize。)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:variable name="exclude" select="('City Three','City Six','City Nine')"/>

    <xsl:template match="city[not(.=$exclude)]">
        <city position="{position()}">
            <xsl:attribute name="number">
                <xsl:number count="city[not(.=$exclude)]"/>
            </xsl:attribute>
            <xsl:value-of select="."/>
        </city>
    </xsl:template>

    <xsl:template match="city"/>

</xsl:stylesheet>

<强>输出

<cities>
   <city position="1" number="1">City One</city>
   <city position="2" number="2">City Two</city>
   <city position="4" number="3">City Four</city>
   <city position="5" number="4">City Five</city>
   <city position="7" number="5">City Seven</city>
   <city position="8" number="6">City Eight</city>
   <city position="10" number="7">City Ten</city>
</cities>