У меня есть блок XSLT, который может применяться несколько раз во всем преобразовании. Но я хочу, чтобы он на самом деле запускался только в первый раз, когда он был применен, это shoul будет пропущено все субкультурные времена. Как мне это сделать?В XSLT, могу ли я запустить шаблон только один раз
В качестве примера, это такая вещь, что я хочу сделать: В таблице стилей я определить глобальную переменную:
<xsl:variable name="run_once" select="0"/>
Тогда я шаблон, который называется несколько раз:
<xsl:template name="some_template">
<xsl:if test="$run_once != 1">
<xsl:variable name="run_once" select="1"/>
<xsl:text>THIS TEXT SHOULD APPEAR ONLY ONCE</xsl:text>
</xsl:if>
</xsl:template>
Это не работает, потому что переменные не могут быть изменены, только перегружены. Итак, как только some_template выходит из $ run_once, снова 0, и текст применяется каждый раз при вызове шаблона. Есть ли какой-либо тип функции ifdef или другой глобальный объект, который я могу установить?
Если вы заинтересованы в том, почему я хочу сделать это, ниже приводится более подробное объяснение моей проблемы и решение, которое я использовал:
- Мой ввод данных в необработанном XML, мой вывод является отчет в формате WordML.
- На входе у меня есть ряд узлов (по имени theNode). Некоторые, но не все, из этих узлов должно быть , отображаемое на выходе. Узел должен отображаться только в том случае, если истинна длина строки (x): (0) hairyLogic (волосистая логика, очевидно, длинная и ).
- theNode также имеет тип (хранится в подэлемент). На входе все theNode того же типа будут всегда сгруппированы вместе. На выходе все номера этого типа должны быть сгруппированы под конкретным заголовком для этого типа (там должен быть только одним заголовком для каждого типа ).
Это решение, которое я закончил с использованием:
...
<xsl:apply-templates select="theNode[hairyLogic]"/>
...
<xsl:template match="theNode">
<xsl:if test="count(preceding-sibling::theNode[type = current()/type and hairyLogic])=0">
<xsl:choose>
<xsl:when test="type = 'TYPE1a' or type = 'TYPE1b'">
<xsl:call-template name="TYPE1Heading"/>
</xsl:when>
<xsl:when test="type = 'TYPE2'">
<xsl:call-template name="TYPE2Heading"/>
</xsl:when>
</xsl:choose>
</xsl:if>
...
</xsl:template>
Я решил использовать именованные шаблоны для заголовков, потому что они содержат основную WordML, что не зависит от каких-либо данных во входном XML.
Мне не нравится это решение, потому что hairyLogic повторяется, а инструкция if свернута и трудно читается. Может быть, у вас есть лучшее решение, которое не требует переменных переменных?
«Что такое XSLT, эквивалентный pythonic? Xslt-y?» - это «декларативный» –
Да, у меня есть ограничения, которые я не полностью детализировал (добавил к вопросу, если вам интересно). Я решил проблему так, как вы описываете. Мне это не нравится, потому что «somelogic» длинный, грязный и теперь повторяется несколько раз. Это было бы не так плохо, если бы я мог диктовать, когда код XPATH анализируется, как я могу на других функциональных языках. Затем я мог бы хранить бит «somelogic» в переменной и вставлять его в мои выражения, когда это необходимо. – oillio