<xsclass="underline" namespace-alias
stylesheet-prefix="#default"
result-prefix="a"/>
означает, что элементы, принадлежащие в преобразовании пространству имен по умолчанию, в выходящем документе должны принадлежать пространству имен а.
<xsclass="underline" stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="urn:a"
xmlns="urn:b">
<xsclass="underline" namespace-alias
stylesheet-prefix="#default"
result-prefix="a"/>
<xsclass="underline" namespace-alias
stylesheet-prefix="a"
result-prefix="#default"/>
<xsclass="underline" template match="root">
<result>
<a:element/>
</result>
</xsclass="underline" template>
</xsclass="underline" stylesheet>
<result xmlns="urn:a" xmlns:a="urn:b">
<a:element/>
</result>
Результатом этого преобразования является то, что пространство имен с URI "urn:а" стало пространством имен по умолчанию, а пространство имен с URI "urn:b" изменило префикс на а.
В преобразованиях можно объявлять несколько псевдонимов пространств имен при условии, что одно и то же пространство имен преобразования не должно быть объявлено элементами xsclass="underline" namespace-alias с одинаковым порядком импорта псевдонимом для различных пространств имен выходящего документа.
Если преобразование a.xsl содержит определение
<xsclass="underline" namespace-alias
stylesheet-prefix="x"
result-prefix="a"/>
а преобразование b.xsl — определение
<xsclass="underline" namespace-alias
stylesheet-prefix="x"
result-prefix="b"/>
где в обоих преобразованиях префикс x представляет одно пространство имен, а пространства имен a и b — разные, то преобразование a.xsl не сможет включать преобразование b.xsl и наоборот, потому что они будут иметь одинаковый порядок импорта и содержать элементы xsclass="underline" namespace-alias, назначающие разным пространствам имен одинаковые псевдонимы. В одном преобразовании такие псевдонимы также не имеют права встречаться. Если же подобное все же случилось, процессор может сигнализировать ошибку или использовать определение, которое было дано в преобразовании последним.
Совсем иначе обстоит дело с импортированием. При импортировании определения старших в порядке импорта преобразований могут переопределять определения младших преобразований. Таким образом, если преобразование a.xsl будет импортировать преобразование b.xsl, пространство имен x будет назначено псевдонимом пространству имен а и наоборот.
Ключи
Прежде чем мы приступим к разбору ключей, которые являются одной из самых мощных концепций языка XSLT, попробуем решить одну несложную задачку.
<items>
<item source="a" name="A"/>
<item source="b" name="B"/>
<item source="a" name="C"/>
<item source="c" name="D"/>
<item source="b" name="E"/>
<item source="b" name="F"/>
<item source="c" name="G"/>
<item source="a" name="H"/>
</items>
Пусть входящий документ представляет собой список объектов (элементов item), каждый из которых имеет имя (атрибут name) и источник (атрибут source). Требуется сгруппировать объекты по своим источникам и получить документ приблизительно следующего вида.
<sources>
<source name="a">
<item source="a" name="A"/>
<item source="a" name="C"/>
<item source="a" name="H"/>
</source>
<source name="b">
<item source="b" name="B"/>
<item source="b" name="E"/>
<item source="b" name="F"/>
</source>
<source name="c">
<item source="c" name="D"/>
<item source="c" name="G"/>
</source>
</sources>
Первым шагом на пути решения этой задачи является формулировка в терминах XSLT предложения "сгруппировать объекты по своим источникам". Источник каждого объекта определяется его атрибутом source, значит множество объектов, принадлежащих одному источнику "а", будет определяться путем выборки
/items/item[@source='a']
Тогда для каждого элемента item в его группу войдут элементы, которые будут выбраны выражением
/items/item[@source=current()/@source]
Попробуем использовать этот факт в следующем шаблоне:
<xsclass="underline" template match="item">
<source name="{@source}">
<xsclass="underline" copy-of select="/items/item[@source=current()/@source]"/>
</source>
</xsclass="underline" template>
Как и ожидалось, при применении этого правила к элементам item для каждого из них будет создана группа, принадлежащая тому же источнику, — уже хороший результат, но в условии требуется создать по группе не для каждого объекта, а для каждого источника. Чтобы достичь этого, можно создавать группу только для первого объекта, принадлежащего ей. Провести такую проверку опять же несложно: объект будет первым в группе тогда и только тогда, когда ему не предшествуют другие, элементы item, принадлежащие тому же источнику. Иначе говоря, создаем группы только для тех элементов, для которых выражение
preceding-sibling::item[@source-current()/@source]
будет возвращать пустое множество.
С небольшими добавлениями искомое преобразование целиком будет иметь вид.
<xsclass="underline" stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsclass="underline" template match="items">
<sources>
<xsclass="underline" apply-templates/>
</sources>
</xsclass="underline" template>
<xsclass="underline" template match="item">
<xsclass="underline" choose>
<xsclass="underline" when
test="preceding-sibling::item[@source=current()/@source]"/>