Я пытаюсь применить постоянное свертывание к представлениям XML простых числовых выражений.Свертывание констант - это процесс замены константных (под) выражений их буквальным значением.Часть постоянного свертывания заменяет каждую двоичную операцию, которая применяется к двум литеральным значениям, на вычисляемый литеральный результат.Скажем, у нас есть выражение:
1+x+2*(3+1)
и его XML-представление:
<addition>
<addition>
<value>1</value>
<variable>x</variable>
</addition>
<multiplication>
<value>2</value>
<addition>
<value>3</value>
<value>1</value>
</addition>
</multiplication>
</addition>
мы можем заменить
<addition>
<value>3</value>
<value>1</value>
</addition>
на
<value>4</value>
И впоследствии мы можем заменить
<multiplication>
<value>2</value>
<value>4</value>
</multiplication>
на
<value>8</value>
Окончательный результат должен выглядеть следующим образом (его можно еще больше упростить, но пока этого достаточно):
<addition>
<addition>
<value>1</value>
<variable>x</variable>
</addition>
<value>8</value>
</addition>
Часть моей таблицы стилей XSLT выглядит следующим образом:
<xsl:template match="addition[count(value) = 2]">
<value>
<xsl:value-of select="value[1] + value[2]" />
</value>
</xsl:template>
<xsl:template match="multiplication[count(value) = 2]">
<value>
<xsl:value-of select="value[1] * value[2]" />
</value>
</xsl:template>
...
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
Идея этого шаблона заключается в рекурсивной замене всех элементов операции (сложение, умножение, ...), для которыхоба операнда (дочерние) являются элементами значения, причем один элемент значения содержит вычисленное значение.Оставшаяся часть дерева (операции, содержащие переменные) должна оставаться неизменной.
Однако эта таблица стилей будет применять константное свертывание только один раз, заменяя только самые глубокие двоичные элементы операции их литеральным значением.Единственный способ заставить эту таблицу стилей работать - продолжать преобразовывать выходные данные последнего преобразования, пока входной и выходной документы не совпадут.Я новичок в XSLT, поэтому уверен, что для этого должен быть более естественный способ.