Вы можете использовать
<xsl:value-of select="count(preceding-sibling::record)" />
или даже, вообще,
<xsl:value-of select="count(preceding-sibling::*[name() = name(current())])" />
Конечно, этот подход не будет работать, если вы обрабатываете список неравномерных узлов, то есть:
<xsl:apply-templates select="here/foo|/somewhere/else/bar" />
Информация о местоположении теряется в таком случае, , если вы не сохраните ее в переменной и не передадите ее в вызываемый шаблон:
<xsl:variable name="pos" select="position()" />
<xsl:for-each select="$record">
<xsl:call-template name="SomeTemplate">
<xsl:with-param name="pos" select="$pos" />
</xsl:call-template>
</xsl:for-each>
, но, очевидно,это означало бы переписывание кода, которого, как я понимаю, вы хотите избежать.
Заключительный совет: position()
не не говорит вам о положении узла в его родительском элементе.Он сообщает вам позицию текущего узла относительно списка узлов, которые вы сейчас обрабатываете .
Если вы обрабатываете (т. Е. «Применяете шаблоны к» или «перебираете») узлы в пределах одного родителя, это может быть одним и тем же.Если нет, это не так.
Заключительный совет № 2: Этот
<xsl:for-each select="/path/to/record">
<xsl:variable name="record" select="."/>
<xsl:for-each select="$record">
<xsl:call-template name="SomeTemplate"/>
</xsl:for-each>
</xsl:for-each>
эквивалентен следующему:
<xsl:for-each select="/path/to/record">
<xsl:call-template name="SomeTemplate"/>
</xsl:for-each>
, но последний работает без , уничтожая смысл position()
.Вызов шаблона не меняет контекст, поэтому .
будет ссылаться на правильный узел внутри вызываемого шаблона.