Псевдонимы пространств имен
Псевдонимы пространств имен
Любопытным фактом является то, что XML-документ, являющийся результатом выполнения XSLT-преобразования, может и сам быть XSLT- преобразованием. Иными словами, преобразования могут генерироваться другими преобразованиями. В некоторых случаях такая возможность будет очень полезна, например, входящий XML-документ может описывать преобразование, которое нужно сгенерировать.
Листинг 8.13. XML-документ, описывающий требуемое преобразование
<transform>
<remove select="a"/>
<replace select="b" with="B"/>
<replace select="c" with="C"/>
</transform>
Приведенный выше документ описывает преобразование, которое должно удалять из входящего документа элементы а, а элементы b и c заменять элементами B и C соответственно. Такое преобразование может выглядеть следующим образом.
Листинг 8.14. Преобразование
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="a"/>
<xsl:template match="b">
<xsl:element name="B">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="c">
<xsl:element name="C">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Преобразование, генерирующее такой код, не представляет особой сложности. Например, шаблон для обработки элемента replace может иметь следующий вид:
<xsl:template match="replace">
<xsl:element name="xsl:template">
<xsl:attribute name="match">
<xsl:value-of select="@select"/>
</xsl:attribute>
<xsl:element name="xsl:element">
<xsl:attribute name="name">
<xsl:value-of select="@with"/>
</xsl:attribute>
<xsl:element name="xsl:apply-templates"/>
</xsl:element>
</xsl:element>
</xsl:template>
Шаблон этот выглядит очень громоздко, потому что мы не могли просто включить в него создаваемое правило: поскольку мы создаем элементы в пространстве имен XSLT, находясь в шаблоне, они воспринимались бы не как генерируемые, а как принадлежащие генерирующему преобразованию. Очевидно, что шаблон вида
<xsl:template match="replace">
<xsl:template match="{@select}">
<xsl:element name="{@with}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:template>
был бы некорректен. По этой причине нам пришлось генерировать все инструкции при помощи xsl:element и xsl:attribute, что сделало шаблон громоздким и малопонятным.
Если внимательно рассмотреть проблему, то окажется, что она состоит в том, что мы хотим в преобразовании использовать элементы одного пространства имен так, как если бы они относились к другому пространству.
К счастью, XSLT предоставляет легкий и удобный способ для решения такого рода задачи: пространству имен можно назначить псевдоним при помощи элемента xsl:namespace-alias.