Введение в XSL(T)

Введение в XSL(T)

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

Введение

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

 

Что такое XSL(T)?

XSL(T) это аббревиатура от Extandable Stylesheet Language (Transformation) (Расширяемый язык таблицы стилей (Трансформации)). Хотя это и таблица стилей, но она преследует другие цели, нежели CSS. XSL(T) не используется для визуальных эффектов, вместо этого она используется для извлечения (преобразования) данных из XML для представления их с помощью HTML и CSS. Так же в XSL(T) есть динамические свойства, в которых вы можете использовать итерации или операции сравнения в отличии от статичного XML файла.

Почему использовать XSL(T)?

XSL(t) служит для организации огромных XML деревьев так, чтобы каждый смог их прочитать. К примеру сервера поисковых систем Google'а предоставляют запросы как XML. Чтобы обычный пользователь смог прочитать данный запрос, с ним необходимо провести некоторые преобразования. Вот где XSL(T) играет важную роль. Эту технологию так же можно использовать для представления данных как RSS, когда источник весь на XML. Еще XSL(T) используется как основной язык шаблонов для автономных командных проектов (EMC) и в некоторых открытых CMS, как Symphony.

XSL(T) так же снижает нагрузку на сервер. Из-за того что XSL(T) будет выполнятся на стороне клиента, у сервера уменьшиться количество работы. JavaScript и инструкции на сервере могут указывать на использование конкретного XSL(T) шаблона, или можно из шаблона обратиться к самому XML-файлу. В этом руководстве для простоты мы свяжем XSL(T) шаблон с XML файлом.

Давайте начнем

Наша цель создать список мест отдыха, куда мы хотим поехать, и применить немножко логики с данными, чтобы представить куда мы не сможем поехать из-за недостатка финансов. Предположим что бюджет на отдых у нас 999$, и мы хотим видеть, на какие путешествия у нас не хватает денег. Так же мы отсортируем места отдыха в порядки убывания их стоимости, чтобы мы смогли видеть какие поездки находятся вне нашего бюджета.

Прежде всего мы должны создать XML файл. Откройте ваш текстовый редактор и создайте файл с именем trips.xml. Ниже предоставлен код исходного XML файла.
<?xml version="1.0" encoding="ISO-8859-1"?>

<vacation>
      <title>My Loco Vacations</title>
      <trip date="03/01/10">
          <country>USA</country>
          <state>Florida</state>
          <city>Orlando</city>
          <price>1000</price>
      </trip>
      <trip date="04/01/10">
          <country>USA</country>
          <state>Michigan</state>
          <city>Detroit</city>
          <price>600</price>
      </trip>
      <trip date="02/03/2010">
          <country>Spain</country>
          <city>Madrid</city>
          <price>5000</price>
      </trip>
      <trip date="05/01/10">
          <country>USA</country>
          <state>California</state>
          <city>San Jose</city>
          <price>800</price>
      </trip>
  </vacation>

В первую очередь мы в trips.xml должны указать место, где будет хранится наш .xsl файл. В данном слуае мы его назовем как trips.xsl. Добавляем строчку в trips.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="trips.xsl"?>
...


Создание xsl(t) файла

Теперь создаём этот самый trips.xsl. И можем начать создавать стиль. В первую очередь мы должны указать xml-версию и кодировку нашего файла.

<?xml version="1.0" encoding="utf-8"?>
...
Теперь мы можем нырнуть в написание XSL-шаблона. Для написания нашей таблицы стилей нужно указать браузеру, что это xsl-шаблон и какой он версии. Для этого используем тэг xsl:stylesheet. Он оборачивает всю нашу разметку и должен закрываться в конце документа, в противном случаем браузер не будет преобразовывать данные.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
  <!-- More stuff to come -->

</xsl:stylesheet>
...
Если мы хотим, чтобы представление наших данных использовало XHTML по стандартам W3C, мы должны подключить doctype. В нашем примере мы будем использовать XHTML Strict DTD. Для этого используется тэг xsl:output.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>
    
  <!-- More stuff to come -->

</xsl:stylesheet>
...

Далее мы можем начать создавать наш шаблон. Между открытием и закрытием тэга xsl:template находится XHTML-шаблон вперемешку с xsl(t) тегами. Обязательный аттрибут нашего тэга - match. Данный параметр указывает откуда мы будем просматривать наш шаблон. Обычно указывается корень xml документа.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

  <xsl:template match="/">
    
      <!-- More stuff to come -->
    
  </xsl:template>
</xsl:stylesheet>

Преобразования

Создадим XHTML-разметку в тэге xsl:template. Так же подключим файл со стилем style.css:

...
<xsl:template match="/">
  <html>
      <head>
          <title></title>
          <link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
      </head>
      <body>
        
      </body>
  </html>
</xsl:template>
...

Первое, что надо сделать, это взять элемент из XML файла и положить его в заголовок xhtml - страницы.
До того как мы это начнем писать в XSL(T) код, надо понять где в XML-дереве находится элемент title. В данном случае он находится на первом уровне после корня элемента vacation (<title> вложен в <vacation>). Теперь мы можем написать XSL(T) код. Для указания браузеру, где живут данные, нужные нам, будем использовать тэг xsl:value-of.
Сейчас мы находимся в корне документа, указав его в тэге xsl:template, для выбора нужных нам данных мы должны пройтись по xml дереву. В этот раз мы будем просматривать элемент vacation с дочерним элементом title:
<head>
   <title><xsl:value-of select="vacation/title"/></title>
   <link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
</head>

Когда откроем в браузере наш xml-файл (trips.xml), в заголовке браузера отобразиться значения тэга title, и будет он построен по правилам как обычная сверстанная XHTML страница. Мы уже не видим в браузере дерево XML, однако при просмотре исходного кода, мы его увидим.

Для проверки преобразования из xml в xhtml мы можем использовать такие инструменты как FireBug или Safari Inspector

Для более приятного просмотра добавим чуть-чуть разметки, так что наши данные будут лучше выглядеть.
...
</head>
<body>
   <div id="wrapper">
       <div id="trips">
           <h1><xsl:value-of select="vacation/title"/></h1>
               <ul>
                   <li></li>
               </ul>
       </div>
   </div>
</body>
...

Как вы поняли, выше еще раз использовалось значение элемента title, но теперь в тэге body нашей страницы.
Дальше мы должны преобразовать наши поездочки ("trips"). Чувство логики подсказывает писать код используя элемент xsl:value-of только уже с узлом trip, но это будет работать только при существовании одной поездки. У нас же много поездок (мы мотаемся по миру как ангелы и черти) и нам нужно использовать какой-нибудь итерационный метод для нашего xml-файла, чтобы циклом пройти по всем trips.



Итерация (цикл) - <xsl:for-each >

Как и во всех языках программирования, здесь имеются возможности организации циклов, бегающих по данным и использующих методы для работы с ними. Для этого XSL(T) имеет простой функционал.
...
<xsl:for-each select="vacation/trip">
   ...
</xsl:for-each>
...
Выше приведенный код, показывает как мы это можем организовать. В этом примере показано, что тэг xsl:for-each выберет все элементы, которые попадутся с путем vacation/trip.

Как только данные были извлечены, мы должны проделать с ними некоторую работу. Так как наш бюджет $999 (остальное отложено на семью, макбук, машину, квартиру), мы должны придать данным некоторую логику. Перед этим давайте отсортируем данные по цене в убывающем порядке.

 

Сортировка

...
<xsl:for-each select="vacation/trip">
   <xsl:sort select="price" data-type="number" order="descending"/>
   ...
</xsl:for-each>
...

Как вы видите сортировка данных по какому-либо узлу происходит очень просто: при помощи указания специального элемента. Так как xsl:for-each выбирает "trip" и распространяется на то, что вложено внутрь trip, мы можем указать тэг xsl:sort с выбором элемента "price", указать, что интересны данные в виде чисел(data-type="number") и порядок сортировки по убыванию(order="descending"). Так же стоит отметить, что xsl:sort само-закрывающийся тэг.

 

Предварительный просмотр

Теперь мы можем посмотреть как это выглядит. Напомним что в браузере надо открыть trips.xml, а не trips.xsl.
начинаем изучение XSLT и XML
Вы, возможно, удивлены, что ни какие данные не отобразились. Это произошло потому, что мы не указали как отображать данные. Тэг xsl:sort только сортирует элементы и не как не отображает их.

 

Параметры: выборка и сравнение (проверка)

Для обозначения путешествий, которые не укладываются в наш бюджет, мы должны проверить некоторые параметры. Для этого используем 3 тэга - xsl:choose, xsl:when test="" и xsl:otherwise. Если у вас есть какой-нибудь опыт программирования вы легко поймете принцип построения условий. Если нет, то просто перепишите следующий код:
<xsl:for-each select="vacation/trip">
   <xsl:sort select="price" data-type="number" order="descending"/>
   <xsl:choose>
       <xsl:when test="price > 999">
           СЛИШКОМ ДОРОГО
       </xsl:when>
       <xsl:otherwise>
           УСТРАИВАЕТ
       </xsl:otherwise>
   </xsl:choose>
</xsl:for-each>

Мы начинаем построение нашей логике с тэга xsl:choose, который схож с оператором if в других языках программирования. Сразу после этого мы должны сделать проверку (сравнение). В тэге xsl:when мы указываем что будем выводить "СЛИШКОМ ДОРОГО" если цена больше чем 999$. Иначе выводим "УСТРАИСВАЕТ".
Теперь мы должны заменить "СЛИШКОМ ДОРОГО" и "УСТРАИСВАЕТ" на наши элементы из xml-файла.
<xsl:choose>
   <xsl:when test="price > 999">
       <li class="too-much">$<xsl:value-of select="price"/> <xsl:value-of select="city"/>, <xsl:value-of select="state"/> <xsl:value-of select="country" /> <em><xsl:value-of select="@date"/></em> </li>
   </xsl:when>
   <xsl:otherwise>
       ...
   </xsl:otherwise>
</xsl:choose>
В приведенном выше коде, мы указываем элементу списка класс "too-much". Данный класс будет закрашивать в красный цвет поездки, которые нам не по карману. Для вытаскивания цены поездки, города, штата, страны и даты поездки используется тэг xsl:value-of. Стоит обратить внимание на то, что для получения атрибута "date" у каждого элемента "trip" используется символ "@". Эта же конструкция была использована раньше, для получения заголовка нашего списка. Мы добавим символ "$" и "," для правильного форматирования данных.
<xsl:choose>
   <xsl:when test="price > 999">
       <li class="too-much">$<xsl:value-of select="price"/> <xsl:value-of select="city"/>, <xsl:value-of select="state"/> <xsl:value-of select="country" /> <em><xsl:value-of select="@date"/></em> </li>
   </xsl:when>
   <xsl:otherwise>
       <li>$<xsl:value-of select="price"/> <xsl:value-of select="city"/>, <xsl:value-of select="state"/> <xsl:value-of select="country" /> <em><xsl:value-of select="@date"/></em> </li>
   </xsl:otherwise>
</xsl:choose>
Теперь мы указываем, что мы должны делать если наша поездка укладывается в рамки бюджета. В данном случаем мы выводим данные в элемент списка, не указывая специального класса. Мы выводим все элементы, точно также как мы это делали для элементов с классом "too-much".



Что у нас получилось.

trips.xsl:  
    <?xml version="1.0" encoding="utf-8"?>

    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

        <xsl:template match="/">
        <html>
            <head>
                <title><xsl:value-of select="vacation/title"/></title>
                <link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
            </head>
            <body>
                <div id="wrapper">
                    <div id="trips">
                        <h1><xsl:value-of select="vacation/title"/></h1>
                            <ul>
                                <xsl:for-each select="vacation/trip">
                                    <xsl:sort select="price" data-type="number" order="descending"/>
                                        <xsl:choose>
                                            <xsl:when test="price > 999">
                                                <li class="too-much">$<xsl:value-of select="price"/> <xsl:value-of select="city"/>, <xsl:value-of select="state"/> <xsl:value-of select="country" /> <em><xsl:value-of select="@date"/></em> </li>
                                            </xsl:when>
                                            <xsl:otherwise>
                                                <li>$<xsl:value-of select="price"/> <xsl:value-of select="city"/>, <xsl:value-of select="state"/> <xsl:value-of select="country" /> <em><xsl:value-of select="@date"/></em> </li>
                                            </xsl:otherwise>
                                        </xsl:choose>
                                </xsl:for-each>
                            </ul>
                    </div>
                </div>
            </body>
        </html>
        </xsl:template>
    </xsl:stylesheet>

На этот раз мы увидим в браузере что-то полезное, откройте trips.xml:

начинаем изучение XSLT и XML

XSL(T) - мощное средство, с которым вы  радикально измените представление данных из XML.

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Вы можете почитать все статьи от almix'а.




Комментарии (0)     Подпишитесь на RSS комментариев к этой статье.