Результат этого преобразования приведен на следующем листинге.
Листинг 10.12.
Выходящий документ
<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
на элементы
с
.
Листинг 10.13. Преобразование first.xsl
<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>
</xsl:stylesheet>
Листинг 10.14.
Преобразование second.xsl
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="b">
<c>
<xsl:apply-templates select="@*|node"/>
</c>
</xsl:template>
<xsl:template match="@*|node">
<xsl:copy>
<xsl:apply-templates select="@*|node"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Для того чтобы последовательно применить два этих преобразования к некоторому входящему документу
В результате этих вызовов XSLT-процессор Xalan сначала применит преобразование
first.xsl
к документу
a.xml
и сохранит результат в файле
b.xml
, а затем обработает полученный документ
b.xml
при помощи преобразования
second.xml
и сохранит результат в файле
c.xml
.
В качестве альтернативы, например, для тех случаев, когда пакетная обработка невозможна, мы можем создать преобразование, последовательно применяющее шаблоны преобразований
first.xsl
и
second.xsl
к входящему документу. Для этого:
□ назначим шаблонам преобразования
first.xsl
режим
first
, а шаблонам преобразования
second.xsl
— режим
second
;
□ в основном шаблоне применим шаблоны режима
first
к узлам входящего документа, сохранив результат в переменной
b
;
□ приведем результирующее дерево, содержащееся в переменной
b
ко множеству узлов;
□ обработаем полученное множество узлов шаблонами режима