Относительно «запустить другую итерацию в середине обработанного XML, который удалит дубликаты» - это возможно в XSLT 2.0 или при наличии расширения набора узлов в XSLT 1.0. Но я не думаю, что это необходимо в этом случае.
Вместо «для каждого» и «выбирай, когда проверяешь», в противном случае примените шаблоны:
<xsl:apply-templates select="var" />
Затем у вас есть шаблон для каждого типа переменной, который вы хотите обработать, примерно соответствующий вашему xsl: when elements:
<xsl:template match="var[@value = 'a-value']">
<var value="new-a-value"> new-a </var>
</xsl:template>
А для ч / б предметов что-то вроде:
<xsl:template match="var[@value = 'b-value' or @value = 'c-value'][1]">
<var value="new-b-and-c-value"> new-b-and-c </var>
</xsl:template>
[1]
запускает шаблон только для первой такой переменной среди своих братьев и сестер. Будет ли это именно то, что вы хотите, зависит от того, как может измениться структура вашего ввода.
Но учитывая ваш пример ввода, это работает. Вам также понадобится шаблон для обработки переменных b или c, которые не являются первыми:
<xsl:template match="var[@value = 'b-value' or @value = 'c-value']"
priority="-1" />
Обратите внимание на пустое тело; и низкий приоритет, так что переменные b / c, которые являются первыми, не будут обработаны этим шаблоном.
Подводя итог, учитывая ваш пример ввода, следующая таблица стилей XSLT дает запрашиваемый вывод:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/variables">
<xsl:copy>
<xsl:apply-templates select="var"/>
</xsl:copy>
</xsl:template>
<xsl:template match="var[@value = 'a-value']">
<var value="new-a-value"> new-a </var>
</xsl:template>
<xsl:template match="var[@value = 'b-value' or @value = 'c-value'][1]">
<var value="new-b-and-c-value"> new-b-and-c </var>
</xsl:template>
<xsl:template match="var[@value = 'b-value' or @value = 'c-value']"
priority="-1" />
<xsl:template match="var[@value = 'd-value']">
<var value="new-d-value"> new-d </var>
</xsl:template>
</xsl:stylesheet>
Если это как-то не соответствует тому, что вы имели в виду, дайте мне знать, и мы можем повторить.
Если вы знаете, что на входе будет только один «b», вы можете упростить его и просто иметь шаблон, соответствующий «b», и заменить его новым значением; и иметь пустой шаблон, чтобы соответствовать 'c' и выбросить его. Но это звучало так, как будто ты не можешь сделать такое предположение ...