XSLT:передавать значение от одного для каждого совпадения к следующему
Вопрос
Я использую следующее, чтобы сопоставить все <section>
s с установленным атрибутом ревизии. <section>
может отображаться на многих различных уровнях дерева документов, всегда содержащихся в <chapter>
s.
<xsl:for-each select="//section[@revision]">
<!-- Do one thing if this is the first section
matched in this chapter -->
<!-- Do something else if this section is in the same
chapter as the last section matched -->
</xsl:for-each>
Как говорится в комментариях, мне нужно сделать так, чтобы каждый for-each
итерация осведомлена о главе, к которой относится Предыдущая страница соответствующий раздел принадлежал.Я знаю это <xsl:variable>
s фактически являются статическими после установки, и это <xsl:param>
применяется только к вызывающим шаблонам.
Поскольку это Docbook, я могу восстановить номер главы раздела с помощью:
<xsl:apply-templates select="ancestor::chapter[1]" mode="label.markup" />
но я думаю, что это можно сделать с помощью чисто XPath.
Есть какие-нибудь идеи?Спасибо!
Решение
Не уверен, что я понял ваши требования на 100%, но…
<xsl:variable name="sections" select="//section[@revision]" />
<xsl:for-each select="$sections">
<xsl:variable name="ThisPos" select="position()" />
<xsl:variable name="PrevMatchedSection" select="$sections[$ThisPos - 1]" />
<xsl:choose>
<xsl:when test="
not($PrevMatchedSection)
or
generate-id($PrevMatchedSection/ancestor::chapter[1])
!=
generate-id(ancestor::chapter[1])
">
<!-- Do one thing if this is the first section
matched in this chapter -->
</xsl:when>
<xsl:otherwise>
<!-- Do something else if this section is in the same
chapter as the last section matched -->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
Тем не менее, я подозреваю, что вся эта проблема может быть решена более элегантно с помощью <xsl:template>
/ <xsl:apply-templates>
подходите.Но, не видя ваших входных данных и ожидаемого результата, об этом трудно сказать.
Другие советы
position() вернет вашу позицию в пределах текущей для каждой итерации.Первая итерация, IIRC, вернет 0, поэтому проверка на "position()= 0" покажет вам, находитесь ли вы на первой итерации.