Условия 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>
обратите внимание:
для того, чтобы дать значения переменной (
$voutType
),на<xsl:choose>
инструкция должна быть внутри тело<xsl:variable>
вам нужно только указать
<Class>
элемент после -- вне всего остального.вы не должны использовать
<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 значений. Не уверен, помогает ли это, но он организует код таким образом, что можно.