Условия XSLT / область переменных

<xsl:choose>
    <xsl:when test="long convoluted expression">
        <xsl:element name="Class">123</xsl:element>
        <a lot more xsl:elements>
    </xsl:when>
    <xsl:when test="next very long expression">
        <xml:element name="Class">124</xsl:element>
        <a lot more xsl:elements>
    </xsl:when>
    <tens of more similar xsl:when>
</xsl:choose>

есть ли способ упростить приведенный выше код с помощью условных обозначений? Для каждого значения класса задаются объекты, далее следуют десятки строк с дополнительными атрибутами. Эти атрибуты формируют наборы в соответствии со значением класса. Класс 0-99 имеет один набор дополнительных тегов, класс 100-199 в секунду, образуя кошмар обслуживания при изменении одного из этих дополнительных наборов тегов.

Я рассматривал такое решение:

<xsl:choose>
    <xsl:when test="long convoluted expression">
        <xml:element name="Class">123</xsl:element>
        <xsl:variable name="outputclass" select="123">
    </xml:when>
    <xsl:when test="next very long expression">
        <xml:element name="Class">124</xsl:element>
        <xsl:variable name="outputclass" select="124">
    </xsl:when>
</xsl:choose>
<xsl:choose>
    <xsl:when test="$outputclass > 99">
        <xml:elements for classes 100-199 here>
    </xsl:when>
<xsl:choose>

но, конечно, это не удается, так как переменная outputclass не находится в той же области. Есть способ обойти это?

3 ответов


лучшее решение этой проблемы хорошо известно:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
    <xsl:variable name="voutType">
      <xsl:choose>
        <xsl:when test="long convoluted expression">123</xsl:when>
        <xsl:when test="next very long expression">124</xsl:when>
        <!-- Etcetera ... -->
      </xsl:choose>
    </xsl:variable>

   <Class><xsl:value-of select="$voutType"</Class>
         <xsl:choose>
            <xsl:when test="not($voutType > 99)">
                <!-- elements for classes 0 - 99 here -->
            </xsl:when>
            <xsl:otherwise>
                <!-- elements for classes 100-199 here -->
            </xsl:otherwise>
         <xsl:choose>
 </xsl:template>
</xsl:stylesheet>

обратите внимание:

  1. для того, чтобы дать значения переменной ($voutType),на <xsl:choose> инструкция должна быть внутри тело <xsl:variable>

  2. вам нужно только указать <Class> элемент после -- вне всего остального.

  3. вы не должны использовать <xsl:element> если имя элемента известно.


Если вы пытаетесь сделать его легко указать кучу атрибутов (не теги элементы ака!), то мне кажется, что наборы атрибутов-это то, что вам нужно, и вам могут не понадобиться переменные:

http://www.w3.org/TR/xslt#attribute-sets

это предполагает, что значения атрибутов сами по себе не зависят от значения класса; только их присутствие.

Если элементы действительно то, что вы имеете в виду, попробуйте использовать именованные шаблоны с входным параметром. На верхнем уровне таблицы стилей:

<xsl:template name="classdef">
  <xsl:param name="classid"/>
  <!-- Note: I put the class elem in here so I don't have to
        write individual class ids more than once -->
  <xsl:element name="Class"><xsl:value-of select="$classid"/></xsl:element>
  <xsl:choose>
    <xsl:when test="$classid > 99">
      ...
    </xsl:when>
  </xsl:choose>
</xsl:template>

и в другом шаблоне:

<xsl:call-template name="classdef">
  <xsl:with-param name="classid">124</xsl:with-param>
</xsl:call-template>

см.http://www.w3.org/TR/xslt#variables для получения дополнительной информации о params.


Я делал XSLT всего несколько раз, но каждый раз это кажется огромным кошмаром обслуживания. Во всяком случае, я думаю, что вы можете установить переменную, говорящую, что такое класс, а затем вызвать функцию как xsl:template match с классом как arg. Вы объявите эту функцию как имя xsl: template, потому что вы не хотите автоматически совпадать с ней. Внутри функции вы должны иметь возможность выписать эти 100 значений. Не уверен, помогает ли это, но он организует код таким образом, что можно.