xslt сохраняет несколько переменных в области видимости в зависимости от одного теста

У меня много переменных и только два случая. Мой оригинальный подход выходит за рамки:

<xsl:choose>
    <xsl:when test='$something = 6'>
        <xsl:variable name="foo">x</xsl:variable>
        <!-- 50 other variables -->
    </xsl:when>
    <xsl:when test='$something = 7'>
        <xsl:variable name="foo">y</xsl:variable>
        <!-- 50 other variables -->
    </xsl:when>
</xsl:choose>

то есть. позже, с саксонской, XPST0008: Variable x has not been declared (or its declaration is not in scope)

Я думаю, что это будет работать, если я выберу внутри xsl:variable тег, но тогда тесты будут повторяться снова и снова, снова и снова, снова и снова:

<xsl:variable name="foo">
    <xsl:choose>
      <xsl:when test='$something = 6'>x</xsl:when>
      <xsl:when test='$something = 7'>y</xsl:when>
    </xsl:choose>
</xsl:variable>
<!-- 50 other variables, the two tests repeated for each... -->

Есть ли способ сохранить переменные в области видимости, но также не повторять себя?


обновление 1

добавление полных файлов 'sscce' по запросу

оригинальный подход:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:variable name="something">6</xsl:variable>
    <xsl:choose>
        <xsl:when test="$something = '6'">
            <xsl:variable name="foo">x</xsl:variable>
            <!-- 50 other variables -->
        </xsl:when>
        <xsl:when test="$something = '7'">
            <xsl:variable name="foo">y</xsl:variable>
            <!-- 50 other variables -->
        </xsl:when>
    </xsl:choose>
    <xsl:value-of select="$foo"/>
</xsl:template>
</xsl:stylesheet>

подход, который работает, но заставляет повторяться

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:variable name="something">6</xsl:variable>
    <xsl:variable name="foo">
        <xsl:choose>
          <xsl:when test='$something = 6'>x</xsl:when>
          <xsl:when test='$something = 7'>y</xsl:when>
        </xsl:choose>
    </xsl:variable>
    <!-- 50 other variables, the two tests repeated for each... -->
    <xsl:value-of select="$foo"/>
</xsl:template>
</xsl:stylesheet>

пример XML-файла: <xml/>, пример саксонской командной строки: java -jar saxon9he.jar -s:in.xml -xsl:in.xsl -o:out.html

2 ответа

Ну, я бы предпочел обработать этот способ:

<xsl:variable name="something">6</xsl:variable>

<xsl:variable name="var.set">
  <xsl:choose>
    <xsl:when test="$something = '6'">
        <foo>x</foo>
        <bar>xx</bar>
        <!-- 50 other variables, to be inserted as tag -->
    </xsl:when>
    <xsl:when test="$something = '7'">
        <foo>y</foo>
        <bar>yy</bar>
        <!-- 50 other variables, to be inserted as tag -->
    </xsl:when>
  </xsl:choose>
</xsl:variable>

Переменная var.set будет набор узлов, который вы сможете прочитать благодаря exsl:node-set() расширение.

Например, чтобы получить значение для foo (хранится как узел, а не как переменная), используйте что-то вроде: <xsl:value-of select="exsl:node-set($var.set)/foo" />, Таким образом, вы будете обрабатывать одну переменную, как если бы это был массив значений.

PS: в корневой тег вашей таблицы стилей не забудьте добавить exsl объявление пространства имен xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"

Если вы заранее знаете свои отображения, вы можете сохранить их в своем собственном файле.

Таким образом, вместо того, чтобы что-то подобное

<xsl:variable name="var1">
  <xsl:if test="something = 5">x</xsl:if>
</xsl:variable>
<xsl:value-of select="$var1"/>

Вы могли бы иметь это

<xsl:value-of select="document('other.xml')/root/scheme[@number = 5]/@value"/>

С этим как other.xml

<root>
  <scheme number="5" value="x"/>
  <scheme number="6" value="y"/>
</root>

Возможно, вам понадобится более сложный файл other.xml с различными группами цветов для каждой цветовой схемы, но идея будет такой же и полностью исключает тесты и переменные.

Другие вопросы по тегам