идентификатор тогда и только тогда, когда эти два узла совпадают. Это означает, что во время выполнения одного преобразования функция generate-id
будет возвращать один идентификатор для одного и того же узла, а для разных узлов generate-id
обязательно возвратит разные идентификаторы.
□ Возвращаемый идентификатор состоит только из цифр и букв ASCII и начинается буквой, то есть синтаксически является корректным XML-именем и может использоваться как имя элемента, атрибута, как значение ID-атрибута или в любом другом месте, где могут использоваться имена XML.
Кроме этого спецификация оговаривает следующие важные положения, которые мы приведем ниже.
□ Процессор не обязан генерировать один и тот же идентификатор при разных выполнениях преобразования одного и того же документа. Иными словами, если в понедельник процессор
при выполнении преобразования
сгенерирует для узла
документа
идентификатор
, то во вторник тот же процессор
при выполнении того же преобразования
с тем же документом
может сгенерировать для того же самого узла
совершенно другой, отличный от
идентификатор.
□ Форма возвращаемого идентификатора может быть произвольной, но при этом она должна удовлетворять описанному выше синтаксису. Это означает, что каждый процессор может по-своему генерировать идентификатор. Спецификация не определяет никакого стандартного метода реализации функции generate-id
.
□ Генерируемый идентификатор может совпадать, а может и не совпадать со значениями уникальных атрибутов, то есть атрибутов, тип данных которых объявлен в блоке DTD как ID
.
Помимо очевидного применения, например, для явного задания уникального идентификатора в выходящем документе, функция generate-id
совершено неожиданным образом облегчает задачи группировки. Подробнее об этом мы расскажем в
Предположим, что в наших XML-документах изменилась логическая схема: теперь каждый элемент item
должен обладать уникальным атрибутом id
.
Выполнить задачу конвертации может простое преобразование.
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='@*|node()'>
<xsl:copy>
<xsl:apply-templates select='@*|node()'/>
</xsl:copy>
</xsl:template>
<xsl:template match='item'>
<xsl:copy>
<xsl:attribute name='id'>
<xsl:text><xsl:value-of select='generate-id()'/><xsl:text>
</xsl:attribute>
<xsl:apply-templates select='@*|node()'/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
В выходящем документе элементы item
будут иметь уникальные идентификаторы.
<?xml version='1.0' encoding='utf-8'?>
<items>
<item id='b1b1b2' source='a' name='A'/>
<item id='b1b1b4' source='b' name='B'/>
...
<item id='b1b1c34' source='a' name='F'/>
</items>
Сразу оговоримся, что этот способ будет работать не всегда: generate-id
создает идентификатор, который является уникальным среди всех остальных идентификаторов узлов, а не среди всех значений уникальных атрибутов документа. Так что если бы какой-либо элемент имел ID-атрибут со значением b1b1b4
, выходящий документ перестал бы быть правильным. Однако же, если в документе до преобразования вообще не было уникальных атрибутов, все будет в порядке.
Функция
Синтаксис этой функции приведен ниже:
Функция system-property
возвращает значение свойства, которое определяется ее строковым параметром. Аргумент этой функции должен представлять расширенное имя системного свойства. Если процессор не поддерживает свойство с таким именем, функция должна вернуть пустую строку.
Эта функция предназначена для получения информации об окружении, в котором производится преобразование. В стандарте языка указано, что все процессоры в обязательном порядке должны поддерживать следующие системные свойства:
□ xsl:version
— это свойство должно возвращать номер версии языка XSLT, которую поддерживает данный процессор.
□ xsl:vendor
— это свойство должно возвращать текстовую информацию о производителе используемого процессора.
□ xsl:vendor-uri
— это свойство должно возвращать URL производителя — как правило, xsl:vendor-uri
— это адрес Web-сайта производителя процессора.
К сожалению, в первой версии языка XSLT процессоры обязаны поддерживать только эти свойства. Очень полезным, было бы, например, свойство, возвращающее имя преобразования или преобразовываемого файла. К сожалению, ничего подобного в стандарте не предусмотрено.
В качестве примера приведем небольшой шаблон, выводящий в виде комментария информацию о процессоре.
<xsl:template name='info'>
<xsl:comment>
<xsl:text>
 | XSLT Version: </xsl:text>