<xsl:value-of select='.'/>
</option>
</xsl:for-each>
</select>
Если в преобразовании нам понадобится доопределить входящий список кодами RUS
и UKR
, не исправляя входящий документ, можно поступить следующим образом:
□ создать в переменной фрагмент дерева, содержащий элементы item
входящего документа плюс элементы item
, доопределяющие этот список;
□ преобразовать дерево в список узлов;
□ обрабатывать список узлов точно так же, как мы бы обрабатывали сам входящий документ.
Преобразование, реализующее эти три шага, приведено ниже.
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:xalan='http://xml.apache.org/xalan'
exclude-result-prefixes='xalan'>
<xsl:template match='items'>
<!--
| Создаем переменную tree, содержащую элементы item
| входящего документа а также два дополнительных элемента
+-->
<xsl:variable name='tree'>
<xsl:copy-of select='item'/>
<item>RUS</item>
<item>UKR</item>
</xsl:variable>
<!--
| Конвертируем переменную tree во множество узлов,
| результат присваиваем переменной items
+-->
<xsl:variable name='items' select='xalan:nodeset($tree)'/>
<!--
| Обрабатываем узлы $items/item точно так же,
| как мы обрабатывали бы узлы items/item
+-->
<select name='language'>
<xsl:for-each select='$items/item'>
<option>
<xsl:value-of select='.'/>
</option>
</xsl:for-each>
</select>
</xsl:template>
</xsl:stylesheet>
Результат этого преобразования приведен на следующем листинге.
<select name='language'>
<option>ENG</option>
<option>FRE</option>
<option>GER</option>
<option>GRE</option>
<option>ITA</option>
<option>NOR</option>
<option>POR</option>
<option>SPA</option>
<option>USA</option>
<option>RUS</option>
<option>UKR</option>
</select>
Вне всякого сомнения, функция nodeset
является одним из наиболее востребованных в XSLT расширений, ведь возможность не только создавать, но и манипулировать уже созданными древовидными структурами является чрезвычайно полезной.
В качестве одного из примеров применения функции nodeset
можно привести реализацию с ее помощью многошаговых преобразований.
В качестве примера рассмотрим схему трансформации, изображенную на рис. 10.3, в которой документ А сначала нужно обработать преобразованием 1, затем полученный результат (документ В) обработать преобразованием 2. Конечным результатом цепочки преобразований в данном случае является документ С.

Рис. 10.3. Двухшаговое преобразование
При выполнении преобразования процессор применяет шаблоны ко множеству узлов входящего документа и выстраивает результирующее дерево. Таким образом, для того, чтобы повторно применить шаблоны к уже обработанному документу (читай: к полученному дереву), нужно просто иметь возможность преобразовывать дерево во множество узлов.
Представим себе два простых преобразования, first.xsl
и second.xsl
, первое из которых заменяет во входящем документе элементы а
на элементы b
, а второе — элементы b
на элементы с
.
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='a'>
<b>
<xsl:apply-templates select='@*|node()'/>
</b>
</xsl:template>
<xsl:template match='@*|node()'>
<xsl:copy>
<xsl:apply-templates select='@*|node()'/>
</xsl:copy>
</xsl:template>