Мой XML-файл следующие:
<worksheet>
<row>
<rowTitle>RT1</rowTitle>
<rowType>yesorno</rowType>
<subLine>subLine1Content</subLine>
<subLine>subLine2Content</subLine>
</row>
<row>
<rowTitle>RT2</rowTitle>
<rowType>operation</rowType>
<subLine>subLine1Content</subLine>
<subLine>subLine2Content</subLine>
<subLine>subLine3Content</subLine>
</row>
.
.
</worksheet>
в моем xsl, при отображении содержания конкретной строки, я хотел бы добавить класс к элементу HTML, это укажет тип строки, которая это. Я пытался использовать xsl:choose и присвоить значение xsl:variable, но это не работает. Я пытаюсь отобразить строку как
<ol>
<li class="rowTypeBoolean">
RT1
<ul><li>subLineContent1</li>
<li>subLineContent2</li></ul>
</li>
<li class="rowTypeOptions">
RT2
<ul><li>subLineContent1</li>
<li>subLineContent2</li>
<li>subLineContent3</li></ul>
</li>
.
.
</ol>
Отрывок файла XSL
<xsl:template match="row">
<li class="rowClass ${className}">
<xsl:choose>
<xsl:when test="type = 'YESORNO'">
<xsl:variable name="className" select="rowTypeBoolean"/>
</xsl:when>
<xsl:when test="type = 'OPTIONS'">
<xsl:variable name="className" select="rowTypeOptions"/>
</xsl:when>
<xsl:when test="type = 'OPERATION'">
<xsl:variable name="className" select="rowTypeOperation"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="className" select="rowTypeOther"/>
</xsl:otherwise>
</xsl:choose>
<span class="rowTitleClass">
<xsl:value-of select="rowtitle"/>
</span>
<br/>
<ul class="subLineListClass">
<xsl:apply-templates select="subLine"/>
</ul>
</li>
</xsl:template>
Вам необходимо добавить его как атрибут к элементу:
<li>
<xsl:choose>
<xsl:when test="type = 'YESORNO'">
<xsl:attribute name="className">rowTypeBoolean</xsl:attribute>
</xsl:when>
<xsl:when test="type = 'OPTIONS'">
<xsl:attribute name="className">rowTypeOptions</xsl:attribute>
</xsl:when>
<xsl:when test="type = 'OPERATION'">
<xsl:attribute name="className">rowTypeOperation"</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="className">rowTypeOther"</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</li>
Самым наивным решением было бы использовать инструкцию xsl: choose
следующим образом:
<li>
<xsl:attribute name="className">
<xsl:choose>
<xsl:when test="type = 'YESORNO'">rowTypeBoolean</xsl:when>
<xsl:when test="type = 'OPTIONS'">rowTypeOptions</xsl:when>
<xsl:when test="type = 'OPERATION'">rowTypeOperation</xsl:when>
<xsl:otherwise>rowTypeOther</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</li>
Другой способ - использовать встроенную карту (или через fn: document ()
) например:
<li class="{$map[@type = current()/type]|$map[not(@type)]}"/>
С этим элементом верхнего уровня
<map:map xmlns:map="map">
<item type="YESORNO">rowTypeBoolean</item>
<item type="OPTIONS">rowTypeOption</item>
<item type="OPERATIONS">rowTypeOperation</item>
<item>rowTypeOther</item>
</map:map>
<xsl:variable name="map" select="document('')/*/map:map/*" xmlns:map="map"/>
Совсем не обязательно использовать
в преобразовании:
Это преобразование:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="worksheet">
<ol>
<xsl:apply-templates/>
</ol>
</xsl:template>
<xsl:template match="row[rowType='yesorno']">
<li class="rowTypeBoolean">
<xsl:apply-templates/>
</li>
</xsl:template>
<xsl:template match="row[rowType='operation']">
<li class="rowTypeOperation">
<xsl:apply-templates/>
</li>
</xsl:template>
<xsl:template match="row[rowType='options']">
<li class="rowTypeOptions">
<xsl:apply-templates/>
</li>
</xsl:template>
<xsl:template match="row">
<li class="rowTypeOther">
<xsl:apply-templates/>
</li>
</xsl:template>
<xsl:template match="subLine[1]">
<ul>
<xsl:apply-templates select="../subLine" mode="process"/>
</ul>
</xsl:template>
<xsl:template match="subLine" mode="process">
<li><xsl:apply-templates/></li>
</xsl:template>
</xsl:stylesheet>
при применении к предоставленному XML-документу:
<worksheet>
<row>
<rowTitle>RT1</rowTitle>
<rowType>yesorno</rowType>
<subLine>subLine1Content</subLine>
<subLine>subLine2Content</subLine>
</row>
<row>
<rowTitle>RT2</rowTitle>
<rowType>operation</rowType>
<subLine>subLine1Content</subLine>
<subLine>subLine2Content</subLine>
<subLine>subLine3Content</subLine>
</row>
</worksheet>
дает желаемый, правильный результат:
<ol>
<li class="rowTypeBoolean">
<rowTitle>RT1</rowTitle>
<rowType>yesorno</rowType>
<ul>
<li>subLine1Content</li>
<li>subLine2Content</li>
</ul>
<subLine>subLine2Content</subLine>
</li>
<li class="rowTypeOperation">
<rowTitle>RT2</rowTitle>
<rowType>operation</rowType>
<ul>
<li>subLine1Content</li>
<li>subLine2Content</li>
<li>subLine3Content</li>
</ul>
<subLine>subLine2Content</subLine>
<subLine>subLine3Content</subLine>
</li>
</ol>
Обратите внимание:
Используются только простые шаблоны и
. Поэтому вероятность совершения ошибки сведена к минимуму.
Этот код по своей природе является расширяемым и сопровождаемым. При введении нового типа ряда не нужно будет изменять ни один из существующих шаблонов - просто нужно будет добавить новый короткий и простой шаблон, который будет соответствовать элементу row
, имеющему дочерний rowType
с новым значением.
Связка между rowType
и соответствующим значением атрибута class
может быть задана в специальном элементе и/или переменной с глобальным пространством имен (как это сделано в решении Алехандро) или даже в отдельном XML-документе. Тогда у нас может быть только один единственный шаблон, соответствующий ряду
.