Чтение онлайн

ЖАНРЫ

Технология XSLT

Валиков Алексей Н.

Шрифт:

Телом шаблона является элемент

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

Содержимым элемента

message
является элемент
xsl:value-of
, который, в отличие от
message
принадлежит XSLT. Элемент
xsl:value-of
вычисляет XPath-выражение, заданное в его атрибуте
select
, и возвращает результат этого вычисления. XPath-выражение,
"."
, указанное в
select
, возвращает
ту самую часть узла, которая обрабатывается в данный момент, иначе говоря — элемент
msg
.

Переводя на русский язык все вышеперечисленное, можно сказать, что приведенное преобразование содержит единственное правило: если в документе встретится элемент

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

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

Совсем иным является язык XPath, который представлен в нашем примере лаконичным выражением

"."
. XPath не придерживается XML-синтаксиса, напротив, он скорее похож на синтаксис путей в операционных системах — в главе 4 мы покажем, насколько верно это сравнение.

В приведенном преобразовании участвовала и третья синтаксическая конструкция, которая называется в XSLT паттерном (от англ. pattern — образец). Паттерн

msg
, заданный в атрибуте
match
элемента
xsl:template
указывает, какая именно часть XML-документа должна быть обработана этим правилом. Синтаксически паттерны являются XPath-выражениями (но не наоборот), однако смысл их различается. XPath-выражения вычисляются и возвращают результат, паттерны же просто устанавливают соответствие некоторому образцу. В нашем преобразовании паттерн
msg
указывает, что шаблон должен обрабатывать только элементы
msg
и никакие другие.

Каждое из шаблонных правил может вызывать другие шаблонные правила — в этом случае результат выполнения вызванных шаблонов включается в результат выполнения шаблона, который их вызывал. Для того чтобы продемонстрировать этот принцип мы немного перепишем шаблон

"Hello, world!"
с тем, чтобы он возвращал результат в виде HTML-документа.

Листинг 2.2. Преобразование "Hello, world!"' с результатом в HTML

<xsl:stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="/">

<html>

<head>

<title>Message</title>

</head>

<body>

<xsl:apply-templates select="msg"/>

</body>

</html>

 </xsl:template>

 <xsl:template match="msg">

<b>

<xsl:value-of select="."/>

</b>

 </xsl:template>

</xsl:stylesheet>

Результат применения этого преобразования к документу

<msg>Hello, world!</msg>

иллюстрирует листинг 2.3.

Листинг 2.3.
Результат выполнения преобразования

<html>

 <head>

<title>Message</title>

 </head>

 <body>

<b>Hello, world!</b>

 </body>

</html>

В это преобразование мы добавили еще одно шаблонное правило:

<xsl:template match="/">

 <html>

<head>

<title>Message</title>

</head>

<body>

<xsl:apply-templates select="msg"/>

</body>

 </html>

</xsl:template>

Это правило определяет обработку корневого узла — в атрибуте

match
указан паттерн
"/"
, что соответствует корню документа. Шаблон создает элементы
html
,
head
,
title
,
body
и в последний включает результат применения шаблонов к элементу
msg
. Сравнивая тело этого шаблона с результатом выполнения преобразования, можно заметить, что процессор скопировал все элементы, не принадлежащие XSLT, не изменяя их, а элемент
xsl:apply-templates
выполнил, применив шаблон к элементу
msg
и включив в
body
результат (он выделен в листинге полужирным шрифтом).

Продемонстрированная возможность вызова одних правил из других, а также наличие в XSLT таких управляющих конструкций, как

xsl:if
,
xsl:choose
и
xsl:for-each
позволяет простым набором правил реализовывать очень сложную логику преобразования. В XSLT применяется один из основных принципов эффективной разработки: для того чтобы решить задачу, нужно разбить ее на более мелкие части и решить каждую из них по отдельности. Проблемой в данном случае является преобразование, и вместо того, чтобы описывать его целиком, XSLT позволяет определить простые правила обработки каждой из частей, связав эти правила логикой взаимных вызовов и управляющих конструкций.

Отсутствие "побочных" эффектов

Одним из краеугольных принципов XSLT, с которым, увы, нелегко смириться разработчику, работавшему только с процедурными языками, — это отсутствие "побочных" эффектов. Под побочными эффектами в данном случае понимаются изменения в окружении преобразования, которые отражаются на дальнейшем его выполнении.

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

f(x, у) > вернуть x + у;

будет чистой функцией. Сколько бы раз мы ее не вызывали, ее результат все равно будет равен сумме аргументов. Кроме того, результат вычисления f(f(x1, y1), f(x2, y2)) будет равен x1 + y1 + x2 + y2, в каком бы порядке мы не вычисляли эти функции:

Поделиться с друзьями: