<xsl:namespace-alias> XSLT

Элемент xsl:namespace-alias назначает пространству имен выходящего документа пространство имен, которое будет подменять его в преобразовании, иначе говоря — псевдоним.

Не поддерживается браузером Mozilla Firefox.

Элементы-родители:

Синтаксис

XSLT 1.0 и XSLT 2.0

<xsl:namespace-alias
    stylesheet-prefix = "префикс | #default"
    result-prefix = "префикс | #default" />

Атрибуты

  • result-prefixобязательный атрибут, указывает, какому пространству имен назначается псевдоним.
  • stylesheet-prefixобязательный атрибут, указывает, какое пространство имен будет использоваться в качестве его псевдонима в преобразовании.

Оба атрибута содержат префиксы пространств имен, которые, естественно, должны быть ранее объявлены в преобразовании.

В XSLT 2.0 атрибуты result-prefix и stylesheet-prefix могут принимать значение #default. Естественно, это приведет к ошибке при отсутствии пространства имен по умолчанию. Пространство имен по умолчанию определяется записью xmlns=.

Спецификация

Описание и примеры

Любопытным фактом является то, что XML-документ, являющийся результатом выполнения XSLT-преобразования, может и сам быть XSLT- преобразованием. Иными словами, преобразования могут генерироваться другими преобразованиями. В некоторых случаях такая возможность будет очень полезна, например, входящий XML-документ может описывать преобразование, которое нужно сгенерировать.

Листинг 8.13. XML-документ, описывающий требуемое преобразование

<transform>
    <remove select="a"/>
    <replace select="b" with="B"/>
    <replace select="c" with="C"/>
</transform>

Приведенный выше документ описывает преобразование, которое должно удалять из входящего документа элементы a, а элементы 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.

Пример 1

Возвращаясь к генерации преобразования, мы можем изменить пространство имен генерируемых элементов так, чтобы они не воспринимались процессором как элементы XSLT. Для того чтобы в выходящем документе эти элементы все же принадлежали пространству имен XSLT, измененное пространство имен в преобразовании должно указываться как псевдоним этого пространства.

Листинг 8.15. Преобразование, использующее псевдонимы пространств имен

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:axsl="http://www.w3.org/1999/XSL/Transform/Alias">
    <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
    <xsl:template match="replace">
        <axsl:template match="{@select}">
            <axsl:element name="{@with}">
                <axsl:apply-templates/>
            </axsl:element>
        </axsl:template>
    </xsl:template>
    <xsl:template match="remove">
        <axsl:template match="{@select}"/>
    </xsl:template>
    <xsl:template match="transform">
        <axsl:stylesheet version="1.0">
            <xsl:apply-templates/>
            <axsl:template match="@*|node()">
                <axsl:copy>
                    <axsl:apply-templates select="@*|node()"/>
                </axsl:copy>
            </axsl:template>
        </axsl:stylesheet>
    </xsl:template>
</xsl:stylesheet>

В этом преобразовании элемент xsl:namespace-alias указывает на то, что все элементы, принадлежащие в преобразовании пространству имен с URI

http://www.w3.org/1999/XSL/Transform/Alias

в выходящем документе должны принадлежать пространству имен с URI

http://www.w3.org/1999/XSL/Transform

то есть пространству имен XSLT.

Результатом применения этого преобразования к документу из листинга 8.13 будет следующий документ.

Листинг 8.16. Выходящее преобразование

<axsl:stylesheet version="1.0"
    xmlns:axsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <axsl:template match="a"/>
    <axsl:template match="b">
        <axsl:element name="B">
            <axsl:apply-templates/>
        </axsl:element>
    </axsl:template>
    <axsl:template match="c">
        <axsl:element name="C">
            <axsl:apply-templates/>
        </axsl:element>
    </axsl:template>
    <axsl:template match="@*|node()">
        <axsl:copy>
            <axsl:apply-templates select="@*|node()"/>
        </axsl:copy>
    </axsl:template>
</axsl:stylesheet>

В этом сгенерированном преобразовании элементы имеют префикс axsl, но при этом принадлежат пространству имен XSLT.

Атрибуты stylesheet-prefix и result-prefix элемента xsl:namespace-alias могут иметь значения “#default”. Определение вида

<xsl:namespace-alias stylesheet-prefix="a" result-prefix="#default"/>

означает, что элементы, принадлежащие в преобразовании пространству имен a, в выходящем документе должны принадлежать пространству имен по умолчанию. Определение вида

<xsl:namespace-alias stylesheet-prefix="#default" result-prefix="a"/>

означает, что элементы, принадлежащие в преобразовании пространству имен по умолчанию, в выходящем документе должны принадлежать пространству имен a.

Пример 2

Листинг 8.17. Преобразование

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:a="urn:a" xmlns="urn:b">
    <xsl:namespace-alias stylesheet-prefix="#default" result-prefix="a"/>
    <xsl:namespace-alias stylesheet-prefix="a" result-prefix="#default"/>
    <xsl:template match="root">
        <result>
            <a:element/>
        </result>
    </xsl:template>
</xsl:stylesheet>

Листинг 8.18. Выходящий документ

<result xmlns="urn:a" xmlns:a="urn:b">
    <a:element/>
</result>

Результатом этого преобразования является то, что пространство имен с URI “urn:a” стало пространством имен по умолчанию, а пространство имен с URI “urn:b” изменило префикс на a.

В преобразованиях можно объявлять несколько псевдонимов пространств имен при условии, что одно и то же пространство имен преобразования не должно быть объявлено элементами xsl:namespace-alias с одинаковым порядком импорта псевдонимом для различных пространств имен выходящего документа.

Пример 3

Если преобразование a.xsl содержит определение

<xsl:namespace-alias stylesheet-prefix="x" result-prefix="a"/>

а преобразование b.xsl — определение

<xsl:namespace-alias stylesheet-prefix="x" result-prefix="b"/>

где в обоих преобразованиях префикс x представляет одно пространство имен, а пространства имен a и b — разные, то преобразование a.xsl не сможет включать преобразование b.xsl и наоборот, потому что они будут иметь одинаковый порядок импорта и содержать элементы xsl:namespace-alias, назначающие разным пространствам имен одинаковые псевдонимы. В одном преобразовании такие псевдонимы также не имеют права встречаться. Если же подобное все же случилось, процессор может сигнализировать ошибку или использовать определение, которое было дано в преобразовании последним.

Совсем иначе обстоит дело с импортированием. При импортировании определения старших в порядке импорта преобразований могут переопределять определения младших преобразований. Таким образом, если преобразование a.xsl будет импортировать преобразование b.xsl, пространство имен x будет назначено псевдонимом пространству имен a и наоборот.

Пример для XSLT 2.0

Чтобы продемонстрировать использование пространства имен по умолчанию с элементом <xsl:namespace-alias>, мы рассмотрим две таблицы стилей; в одной используется атрибут result-prefix="#default", а в другой – атрибут stylesheet-prefix="#default". Первая таблица стилей:

<?xml version="1.0"?>
<!-- namespace-alias2.xsl -->
<stylesheet version="2.0"
    xmlns="http://www.w3.org/1999/XSL/Transform"
    xmlns:xslout="[что угодно, кроме пространства имен XSL]">
    <output method="xml" indent="yes"/>
    <namespace-alias stylesheet-prefix="xslout" result-prefix="#default"/>
    <template match="/">
        <xslout:stylesheet version="1.0">
            <xslout:output method="xml"/>
            <xslout:template match="/">
                <xslout:copy-of select="."/>
            </xslout:template>
        </xslout:stylesheet>
    </template>
</stylesheet>

Таблица стилей выдает следующий результат:

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <output method="xml"/>
    <template match="/">
        <copy-of select="."/>
    </template>
</stylesheet>

Исходная и сгенерированная таблицы стилей работают, так как все элементы XSLT находятся в пространстве имен по умолчанию http://www.w3.org/1999/XSL/Transform.

Вторая таблица стилей:

<?xml version="1.0"?>
<!-- namespace-alias3.xsl -->
<xsl:stylesheet version="2.0"
    xmlns="[что угодно, кроме пространства имен XSL]"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:namespace-alias stylesheet-prefix="#default" result-prefix="xsl"/>
    <xsl:template match="/">
        <stylesheet version="1.0">
            <output method="xml"/>
            <template match="/">
                <copy-of select="."/>
            </template>
        </stylesheet>
    </xsl:template>
</xsl:stylesheet>

Выходные данные этой таблицы стилей выглядят более типично:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"/>
    <xsl:template match="/">
        <xsl:copy-of select="."/>
    </xsl:template>
</xsl:stylesheet>

См. также

Ссылки

MDN xsl:namespace-alias на MDN
MSDN xsl:namespace-alias на MSDN