<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"  href="/xslt/final.xslt"?><html>
  <head>
    <title>XSLT.  Краткий курс для HTML-верстальщиков (Техника мягкого ввода в XSLT)</title>
    <meta name="css" content=""/>
    <meta name="js" content=""/>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="id" content="34"/>
    <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml"/>
  </head>
  <body>
    <div class="main">
      <div class="wrap">
        <div class="L">
          <h1><a href="/">..</a> / XSLT.  Краткий курс для HTML-верстальщиков (Техника мягкого ввода в XSLT)</h1>
          <ol class="tags big">
            <li>
              <a href="/short_course_for_html-coder">short_course_for_html-coder</a>
            </li>
          </ol>
          <div class="myContent"><h2>Вводная</h2>
<h3>Зачем и почему это написано</h3>
<p>XSLT технологии  начинают входить в реальную жизнь и практику HTML-верстальщиков. Несмотр на кризис в  Яндексе и Рэмблере практически постоянно были открыты вакансии XSLT-верстальщиков. И не только там. Многие отечественные веб-студии, использующие такие распространенные CMS  как   hostCMS и UMI CMS,  сталкивались с с тем, что найти верстальщиков, знающих XSLT  достаточно сложно. Проще обучать на месте.  <br/>
Одна из причин такого положения   в том, что пособий по XSLT на русском языке  нет или почти нет. При этом  большая часть из того, что есть,   мало приспособлено для быстрого изучения предмета.  То что издано на бумаге найти в магазинах невозможно - книги изданы давно, микроскопическими тиражами и давно раскуплены.    <br/>
Эти записки никак не изменят ситуацию. Но м.б. кому-то пригодится.  Писал  я их по большей части для себя. В феврале-марте 2009 в период вынужденного простоя. <br/>
<br/>
<a name="sources"/></p>
<h3>Источники:</h3>
<p>Увы. Найти книги, перечисленные ниже, найти в печатном виде невозможно. В электронном виде некотороые из них есть в электронных библиотеках.</p>
<ol>
    <li><span style="font-weight: bold;">Стивен Холзнер. XSLT библиотека программиста</span>.   ( Издательство "Питер" · 2002 г.   тираж 3000 экз)<br/>
    Это единственная книга, которую я могу порекомендовать в качестве  учебника. Она  достаточно лаконична и написана живым человеческим языком  и рассчитана на тех,  кто не имеет многолетней привычки читать на ночь спецификации W3С.  Книга построена таким образом, что все примеры берут за основу один и тот же XML-источник, поэтому путь от одного примера к другому идет существенно легче.   При желании pdf-версию этого учебника  можно найти в онлайновых библиотеках </li>
    <li><span style="font-weight: bold;">Валиков А. Технология XSLT</span> ( BHV-СПб. 2001 год, тираж 3000 экз.) <br/>
    "Технология XSLT" считается одной из лучших книг, хотя я это мнение не разделяю. Но она была первым русскоязычным печатным источником по этой теме.  Наверное в этом и кроется ее успех.  А может и в другом. В ней  превосходно подобраны примеры решения классических XSLT-задач (сортировки, группировки, операции с множествами и и т.п.), описаны достаточно просто и подробно.</li>
    <li><span style="font-weight: bold;">Майкл Кэй. XSLT. Справочник программиста</span>   (Издательство "Символ-Плюс" · 2002 г.  тираж 2000 экз)   <br/>
    Увы это не учебник. Это справочник. Очень хороший и подробный. Однако отдельные главы очень хорошо объясняют сложные для понимания места в XSLT, а так же саму идеологию и принципы работы XSLT.</li>
</ol>
<p> </p>
<h3>Структура заметок</h3>
<p><br/>
В своих заметках я постараюсь быть как можно короче, пропуская и не комментируя подробно, многие  важные, но не существенные для быстрого старта вещи, отсылая к  другим источникам.   В первую очередь это подборка примеров на сайте <a href="#" title="www.zvon.or/" rel="nofollow" class="external">zvon.org</a>.  Пока заметки находятся на стадии черновика, я буду всюду где смогу давать ссылки на примеры с этого сайта.  <br/>
<br/>
Так же как и в HTML-верстке в XSLT существуют разные подходы к верстке и точно так же существуют разногласия по поводу возможности использования  тех или иных приемов, стилей программирования (вспомним древнюю дискуссию о дивно-табличной верстке).  На практике же,  применяются все методы в различной комбинации, в зависимости от задачи. <br/>
<br/>
Я начну с легких для понимания методов, и  относительно сложными. Относительно, потому что то с чем приходится сталкиваться при верстке <span style="font-weight: bold;">в большинстве случаев</span> не требует особых ухищрений. Сложности возникают, или на очень нетривиальных сайтах,  или там,  где архитекторы проекта поленились проработать структуру данных  и вывалили на  XSLT выполнение нехарактерных и ресурсоемких вычислительных функций.  Сам по себе  XSLT такой же язык стилевых таблиц как и CSS, но с большими возможностями. Большие возможности определяются наличием элементов, характерных для обычных языков программирования (обработка условий, циклы, процедуры, переменные) и специфических элементов <a href="#" title="ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5" rel="nofollow" class="external">функциональных языков</a> программирования,  к которым относится XSLT. Там где возможно я стараюсь проводить аналогии между XSLT, CSS и JavaScript(PHP) и SQL, полагая , что HTML-верстальщик должен иметь представление об этих  языках, и уж в обязательном порядке знать CSS.  </p>
<h3>Примеры и структура  данных</h3>
<p>В заметках рассматривается пример верстки типового сайта на примере  сборника стихов. Для этого составлены несколько XML данных, для трех типовых страниц:</p>
<ol>
    <li>список поэтов</li>
    <li>страница поэта</li>
    <li>страница стихотворения</li>
</ol>
<p>Все примеры будут строиться на основе этих данных. <span style="font-weight: bold;"> </span>Примеры <a href="/doc/xslt_for_beginners.zip">собраны в архиве</a>. Они  разложены по директориям с именами, соответствующие номеру раздела.  </p>
<h3>Инструментарий</h3>
<p>Лучшим инструментом верстки и отладки, на мой взгляд, является  Oxygen XML Editor. На официальном сайте вы можете скачать его trial-версию. Обход триала достаточно простой, но лучше купить. Академическая версия стоит очень немного.   Ниже я напишу как им пользоваться для отладки XSLT-шаблонов. <br/>
<br/>
Есть так же  freeware инструменты, например EditIx, но к сожалению,  они сильно отстают по функционалу от Oxygen.</p>
<h2>1. XML-минимум</h2>
<h3>1.1. Деревья и узлы</h3>
<p>XML  является древовидной структурой, поэтому вам придется усвоить терминологию деревьев.  Принято рассматривать дерево как совокупность узлов, каждый из которых  может быть по отношению к другим дочерним или родительским.  Подробнее см. раздел "<a href="#" title="ru.wikipedia.org/wiki/%D0%94%D1%80%D0%B5%D0%B2%D0%BE%D0%B2%D0%B8%D0%B4%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0" rel="nofollow" class="external">Деревья</a>" в Википедии<br/>
<br/>
Узлы могут быть нескольких видов. Чтобы было более понятно сразу приведу HTML-код, на  примере которого рассмотрю эту типологию.<br/>
<br/>
<span style="font-weight: bold;">Листинг 1</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;html&gt;
                    &lt;!-- Комментарий --&gt;
                  &lt;title&gt;
                          Hello  World!
                 &lt;/title&gt;
                  &lt;meta name="description" content="Первый пример" /&gt;
                  &lt;body style="background:red"&gt;
                           &lt;h1&gt;Hello XSLT World!&lt;/h1&gt;
                           &lt;div&gt;Подражание  Кернигану-Ричи&lt;/div&gt;
                 &lt;/body&gt;
            &lt;/html&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<a name="root"/></p>
<ol>
    <li><span style="font-weight: bold;">Корневой узел.</span> Это абстракция. Его в примере не видно. Корневой узел расположен на уровне выше первого элемента.   Ближайшим аналогом может быть объект document  из<a href="#" title="ru.wikipedia.org/wiki/DOM" rel="nofollow" class="external"> DOM-модели</a> HTML. К счастью, больше таких абстракций не потребуется.</li>
    <li><span style="font-weight: bold;">Узел элемента. </span>Элемент - в примере любой тег с каким-то содержимым.  У него есть начало - открывающий тег (например &lt;div&gt;) и закрывающий тег (&lt;/div&gt;). Элемент может ничего не содержать - быть пустым как тег &lt;br /&gt;. Очень важно сразу почувствовать разницу между  - "узлом" и "элементом".<br/>
    Узел - понятие более широкое.  </li>
    <li><span style="font-weight: bold;">Узел атрибута. </span>То что расположено в теле открывающего тега сразу после его имени. В примере - параметры name и description тега &lt;meta&gt; или стиль, заданный в background. <br/>
    У узла атрибута есть имя и значение.  Узел элемента &lt;meta&gt; содержит два узла атрибутов. Узел элемента body - один узел атрибутов и два  вложенных узлов элементов -  &lt;h1&gt; и &lt;div&gt;<br/>
    (!!! В XSLT  Узел элемента для своих атрибутов явлется родительским. Но узлы его атрибутов не рассматриваются как дочерние)</li>
    <li><span style="font-weight: bold;">Текстовый узел.  </span>Это обычный текст без тегов. Например, текст "Hello World!"  в теге h1. <br/>
    При работе с текстовыми узлами у вас обязательно появятся некоторые проблемы, связанные с тем, что пробелы, табуляции и переносы строк  между тегами так же являются текстовыми узлами и могут по разному обрабатываться в процессе XSLT-преобразований. Об этом я подробно напишу позже.</li>
    <li><span style="font-weight: bold;">Узел комментария. </span>Он и в HTML комментарий. </li>
</ol>
<p>Есть еще два типа узлов - узлы простанства имен и узлы инструкций обработки. Я не буду останавливаться на этом и отсылаю к учебникам, приведенным во <a href="#sources">Введении</a>. <br/>
<br/>
<a name="12"/></p>
<h3>1.2. Верстайте валидно. Или хотя бы "веллформенно"</h3>
<p>Дискуссия о валидности верстки   - тема отдельная и неплодотворная, но для верстки в  XSLT  это совершенно безразлично. Тем кто привык верстать невалидно - может  упорствовать в ереси столько сколько нужно и даже больше. HTML-верстка может быть сколь угодно кривой, но XSLT-шаблон как любой другой XML-документ должен быть обязательно  "хорошо-сформированным" (well-formed). Т.е. должны соблюдаться три основных требования:</p>
<ol>
    <li>XML-документ должен содержать один или более элементов(тегов), один из которых должен быть корневым (в xHTML это &lt;html&gt;)</li>
    <li>Каждый элемент должен содержать содержать закрывающий тег. Пустые элементы должны быть закрыты, подобно html-тегам  &lt;hr/&gt; и &lt;br/&gt;</li>
    <li>Должны соблюдаться правила вложенности. </li>
</ol>
<p> XSLT не исключает совершенно отвратительный стиль  нарезки сайта на шаблоны, при котором открывающие и закрывающие теги находятся в разных шаблонах и файлах, но намного проще делать это правильно, соблюдая три указанных выше правила.  </p>
<h3>1.3 Кодировка</h3>
<p>Кодировка - UTF-8. Про остальные забудьте. Считайте, что их больше не существует. </p>
<h3>1.4 DOCTYPE</h3>
<p>XSLT позволяет вывести документ в любом выходном формате. Но  в примерах я рассматривают только xHTML1.0  Для этого есть две причины. Во-первых, использование HTML4 просто нелогично, хотя бы потому что оcновное назначение XSLT - преобразование одного XML-документа в другой. Во вторых, HTML  не является веллформенным.  И в третьих,   в случае если на выходе преобразования получается веллфоменный XML его можно обработать еще одним или несколькими последовательными преобразованиями. В качестве примера можно привести получение какой-нибудь специфической версии   HTML-страницы. Например версии для печати или мобильного устройства. Ну и самое главное - надо смотреть в будущее. При очередной переверстке через 20-25 лет будет поще перейти на очередную версию HTML..</p>
<h3>1.5 Мнемоники</h3>
<p>Мнемоники - постоянная головная боль для HTML-верстальщиков, которые впервые сталкивается с XSLT. В HTML верстке привычные спецсимволы типа неразрывного пробела (&amp;nbsp;), копирайта (&amp;copy;) и т.п. обычно заменяются псевдонимами- именными мнемониками. В XSLT эти именные мнемоники не работают, за небольшим исключением:  "больше"(&amp;gt;), "меньше" (&amp;lt;), амперсанда (&amp;amp;).   Символы  ", и ' также могут быть заменены на   &amp;quot; и &amp;apos; В остальных случаях вместо  именных мнемоник  должны использоваться цифровые мнемоники. Часть из них  в таблице ниже: </p>

<table cellspacing="0" cellpadding="5" class="standard">
    <tbody>
        <tr>
            <th>Символ</th>
            <th align="left">Назначение</th>
            <th>Мнемоника</th>
            <th>Код</th>
        </tr>
        <tr>
            <th> </th>
            <td>неразрывный пробел</td>
            <td>&amp;nbsp;</td>
            <td>&amp;#160;</td>
        </tr>
        <tr>
            <th>«</th>
            <td>направленная влево двойная угловая кавычка</td>
            <td>&amp;laquo;</td>
            <td>&amp;#171;</td>
        </tr>
        <tr>
            <th>»</th>
            <td>направленная вправо двойная угловая <span class="mw-redirect">кавычка</span></td>
            <td>&amp;raquo;</td>
            <td>&amp;#187;</td>
        </tr>
        <tr>
            <th>•</th>
            <td>маркер списка (буллит)</td>
            <td>&amp;bull;</td>
            <td>&amp;#8226;</td>
        </tr>
        <tr>
            <th>"</th>
            <td>двойная кавычка</td>
            <td>&amp;quot;</td>
            <td>&amp;#34;</td>
        </tr>
        <tr>
            <th>©</th>
            <td>знак охраны авторского права</td>
            <td>&amp;copy;</td>
            <td>&amp;#169;</td>
        </tr>
    </tbody>
</table>
<p><br/>
Полный список  можно найти <a href="#" title="ru.wikipedia.org/wiki/%D0%9C%D0%BD%D0%B5%D0%BC%D0%BE%D0%BD%D0%B8%D0%BA%D0%B8_%D0%B2_HTML" rel="nofollow" class="external">здесь</a>. В XSLT есть возможность использования именных мнемоник, но это влечет за собой  дополнительные вычислительные ресурсы, и желательно на этом сэкономить, заменив все что можно на цифровые мнемоники.</p>
<h2>2. Hello XSLT World!</h2>
<h3>2.1. Инструментальное вступление, не обязательное к прочтению</h3>
<p>Если у вас нет никакого инструмента для работы с XSLT - скачайте   trial-версию <a href="#" title="www.oxygenxml.com/download_oxygenxml_editor.html" rel="nofollow" class="external">Oxygen XML  editor</a>. Инсталлируйте и запустите его.Срока работы trial-версии более чем достаточно для изучения XSLT в тех рамках, которыми я ограничусь.  Если есть другой инструмент, перейдите к следующему разделу. <br/>
Итак по шагам.</p>
<ol>
    <li>Нажмите на кнопку с пиктограмкой бага  и подписью XSLT. См. рисунок  ниже (можете нажать на картинку для ее увеличения)<a href="/img/articles/oxygen1.jpg"><img width="100" style="display: block; float: right;" src="/img/articles/oxygen1.jpg" title="oxigen" alt="oxigen"/></a></li>
    <li>Откройте в директории  2 примеров файлы pushkin.xml и hello.xsl</li>
    <li>В крайнем левом листбоксе выберите опцию <a href="#" title="ru.wikipedia.org/wiki/Xalan" rel="nofollow" class="external">Xalan</a>  (этот процессор в Oxygen нормально выводит кириллицу, может так же попробовать другие). <br/>
    <br/>
    <a href="/img/articles/oxygen2.jpg"><img width="100" style="display: block; float: right;" src="/img/articles/oxygen2.jpg" alt=""/></a></li>
    <li>Нажмите кнопку с синей стрелкой для запуска преобразования.  </li>
    <li>В правом окне вы получили желаемый результат.</li>
    <li>В дальнейшей работе, когда будет открыто много XML и XSLT-файлов назначайте XML- источник и XSLT-шаблон, при помощи соответствующих листбоксов в верхней панели редактора.</li>
</ol>
<p>Хотелось бы чуть подробнее остановиться на XSLT-процессорах . Их достаточно много. В  Oxygen они написаны на Java.  Но с Java мало кто имеет счастье сталкиваться на хостинге. Реально приходится работать с PHP или .NET  На этих платформах будут другие процессоры возможно результат их работы будет несколько отличаться в мелочах, например при обработке проблельных сиволов или UTF.  Поэтому возможны определенные нестыковки. Как правило фатального ничего в этом нет. Но это надо иметь ввиду. Если форма вывода предложенного мной <a href="#" title="ru.wikipedia.org/wiki/Xalan" rel="nofollow" class="external">Xalan</a>   вас не устроит - попробуйте другой процессор. <br/>
На первых порах этого будет больше чем достаточно для отладки XSLT  в Oxygen.  Дальше я не возвращаюсь к   теме инструментария  и считаю что вы можете все самостоятельно отладить    </p>
<h3>2.2. Дань традиции</h3>
<p>По традиции, введенной 30 лет назад великими  <a href="#" title="ru.wikipedia.org/wiki/Hello_world%21" rel="nofollow" class="external">Керниганом и Ричи</a> первая программа должна  выводить  страницу с фразой "Hello World!".   Для HTML-верстальщика это должно выглядеть так:<br/>
<br/>
<span style="font-weight: bold;">Листинг 2.2</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;html&gt;
                  &lt;body&gt;
                           &lt;h1&gt;Hello   World!&lt;/h1&gt;
                 &lt;/body&gt;
            &lt;/html&gt;</pre><!--/php--></td></tr></table>
<h3>2.3 Поехали</h3>
<p>Для преобразования по-любому нужно взять что-то, что мы должны преобразовать. Для примера  "Hello XSLT World" совершенно безразличен XML-источник, так как на выходе должен получиться статический текст. Для примера возьмем  файл pushkin.xml, даже не заглядывая в него. А вот xslt-файл, рассмотрим чуть подробнее: <br/>
<br/>
 <span style="font-weight: bold;">Листинг 2.3 hello.xsl<br/>
<br/>
</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
            
                &lt;xsl:template match="/"&gt;
                    &lt;html&gt;
                        &lt;body&gt;
                            &lt;h1&gt;Hello  World!&lt;/h1&gt;
                        &lt;/body&gt;
                    &lt;/html&gt;
                &lt;/xsl:template&gt;
            &lt;/xsl:stylesheet&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Все элементы, относящиеся к XSLT, имеют префикс "xsl:". Это инструкции процессору, осуществляющему преобразование.<br/>
Первый элемент xsl:stylesheet указывает процессору, что это  XSLT версии 1.0 (есть еще и 2.0).  Он общий для всех шаблонов и в текстах я его буду опускать. <br/>
Второй элемент  xsl:template указывает процессору, правило, по которому должен быть преобразован <a href="#root">корневой узел</a>.  <br/>
<br/>
Хотя этот элемент самый важный в XSLT, я подробнее рассмотрю в отдельном разделе (*).  В этом разделе будет один единственный подобный шаблон и в его опции match задается  или корневой узел или узел корневого элемента. <br/>
Процессор выводит все что не относится к XSLT  - те HTML-теги с содержимым, и ищет другие инструкции с префиксом "xsl:".  Поскольку в примере больше никаких инструкций нет, он больше ничего и не делает, кроме копирования  HTML-кода страницы "Hello world!"<br/>
<br/>
Для того чтобы добавить DOCTYPE, соответствующий xHTML  необходимо добавить опцию вывода, сразу после строки <span style="font-style: italic;">xsl:stylesheet:</span><br/>
<br/>
   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
                        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" method="xml"
                        encoding="utf-8" indent="yes" /&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Я пока оставляю параметры этой инструкции без комментариев, и  в дальнейшем не буду приводить ни эту строку ни обертку <span style="font-style: italic;">xsl:stylesheet</span> Они в примерах меняться не будут. <br/>
 <br/>
Необходимо отметить две особенности копирования содержимого xsl инструкций, не относящихся к xsl: <br/>
1) комментарии съедаются. Для включения комментариев во входной поток необходима специальная xsl-инструкция.<br/>
2) пробельные симолы (в том числе переносы строк)  обрабатываются достаточно странно и это отдельная тема. </p>
<h2>3. XSLT. Техника мягкого ввода</h2>
<h3>3.1. По пути xPATH</h3>
<p>В примере "Hello  World" я показал как вывести статический текст. Это не интересно, потому главная задача - научиться строить шаблоны. Т.е. переводить XML-данные в HTML-страницу. Для этого нужно научиться вытаскивать данные из XML. Чтобы было более понятно, я приведу пример простого XML файла с биографическими данным, на котором будет рассматриваться большинство примеров.<br/>
<br/>
<span style="font-weight: bold;">Листинг 3.2.1<br/>
</span>   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;author id="1"&gt;
                    &lt;fio&gt;
                        &lt;f&gt;Пушкин&lt;/f&gt;
                        &lt;i&gt;Александр&lt;/i&gt;
                        &lt;o&gt;Сергеевич&lt;/o&gt;
                    &lt;/fio&gt;
                    &lt;born&gt;1799&lt;/born&gt;
                    &lt;rip&gt;1837&lt;/rip&gt;
                    &lt;registry country="Россия" city="Москва" /&gt;
                    &lt;text&gt;
                        Александр Сергеевич &lt;b&gt;Пушкин&lt;/b&gt;  - наше все! &lt;br /&gt; 
                        Пушкин разбудил &lt;a href="http://en.wikipedia.org/wiki/Lermontov"&gt;Лермонтова&lt;/a&gt;
                    &lt;/text&gt;
            &lt;/author&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
<br/>
Адресация к данным, хранящимя в XML, строится на выражениях языка <a href="#" title="ru.wikipedia.org/wiki/XPath" rel="nofollow" class="external">xPATH</a>.  XSLT и XPATH связаны настолько тесно, что я местами не буду упоминать где из них что.  Самые простые выражения XPATH похожи на пути в файловых системах. Чтобы было понятно о чем речь приведу очевидные фрагменты и HTML-кода: </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;img src="project/images/article/zero.gif" /&gt;
            &lt;link rel="stylesheet" href="/project/css/css.css" type="text/css" /&gt;
            &lt;script language="JavaScript" src="project/js/js.js" type="text/javascript"&gt;&lt;/script&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Cодержимое атрибутов src и href - это пути в фаловой системе.  Пути состоят из цепочек директорий, разделенных слэшем.   Для XML XPATH-пути будут выглядеть аналогичным  образом: <br/>
"/" - путь к корневому узлу<br/>
"/author" - путь к элементу author<br/>
"/author/fio/" - путь к элементу fio, содержащие ФИО<br/>
"/author/fio/f" - путь к элементу, содержащемк фамилию<br/>
<br/>
Так же как и в фаловых системах есть понятие относительного и абсолютного пути. <br/>
Абсолютный путь отсчитывается от корневого узла и начинается с одинарного слэша  "/" как в примерах выше. Относительный путь отсчитывается от текущего положения.  В примерах выше были показаны абсолютные пути. <br/>
<br/>
Есть еще один способ адресации, крайне нежелательный, но  служащий хорошим посдпорьем для  начинающих. Если точная структура XML неизвестна, но точно известно что есть элемент с именем "MYNAME", к нему можно обратиться так:  "//MYNAME". Два слеша означают  означает адресацию к  узлам с указанным именем, независимо от того где они встретятся.   Главное не запутаться, ведь в XML может встретиться не один элемент с именем  MYNAME, а рассмотренные выражения XPATH -  несмотря на сходство не  то же самое что путь в файловой  системе.  В XSLT эти выражения определяют <span style="font-weight: bold;">множество узлов</span>, и  используются  для формирования правил преобразования из входного XML в выходной. <br/>
<br/>
Для адресации к атрибуту элемента необходимо перед его именем добавить префикс "@": <br/>
registry/@country - обращение к атрибуту  country, элемента  registry<br/>
<br/>
Пока этого представления о языке xPATH будет достаточно. </p>
<h3>3.2   Буквально xsl:value</h3>
<p>Для первого примера рассмотрим пример с выводом страницы биографических данных Пушкина. Исходный файл  pushkin.xml   выглядит так:<br/>
<br/>
 <span style="font-weight: bold;">Листинг 3.2.1 (</span>pushkin.xml<span style="font-weight: bold;">)<br/>
<br/>
</span>   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;author id="1"&gt;
                    &lt;fio&gt;
                        &lt;f&gt;Пушкин&lt;/f&gt;
                        &lt;i&gt;Александр&lt;/i&gt;
                        &lt;o&gt;Сергеевич&lt;/o&gt;
                    &lt;/fio&gt;
                    &lt;born&gt;1799&lt;/born&gt;
                    &lt;rip&gt;1837&lt;/rip&gt;
                    &lt;registry country="Россия" city="Москва" /&gt;
                    &lt;text&gt;
                        Александр Сергеевич &lt;b&gt;Пушкин&lt;/b&gt;  - наше все! &lt;br /&gt; 
                        Пушкин разбудил &lt;a href="http://en.wikipedia.org/wiki/Lermontov"&gt;Лермонтова&lt;/a&gt;
                    &lt;/text&gt;
            &lt;/author&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
<br/>
Поробуем изобразить шаблон выводящий только фамилию. Например так:<br/>
<br/>
   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;html&gt;
                &lt;body&gt;
                   &lt;h1&gt;
                      Пушкин
                  &lt;/h1&gt;
                &lt;/body&gt;
            &lt;/html&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Листинг XSLT будет выглядеть так: <br/>
<br/>
 <span style="font-weight: bold;">Листинг 3.2.2 (puschkin-family.xsl)</span><br/>
   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">     &lt;xsl:template match="/"&gt;
                    &lt;html&gt;
                        &lt;body&gt;
                            &lt;h1&gt;
                                &lt;xsl:value-of select="author/fio/f"/&gt;
                            &lt;/h1&gt;
                        &lt;/body&gt;
                    &lt;/html&gt;
                &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p>  <br/>
<br/>
<br/>
Как и в предыдущем примере процессор  по инструкции <span style="font-style: italic;">xsl:template</span> начинает обработку корневого узла  "/", выводит все тексты и HTML-теги из XSLT-шаблона до тех пор, пока не встретит новые xsl-инструкции. Единственная инструкция в примере  <span style="font-style: italic;">xsl:value-of</span>. Эта инструкция указывает процессору, что нужно вывести содержимое узла, указанного в параметре<span style="font-style: italic;"> select</span>. В этом параметре указан путь  к интересующему нас элементу входного дерева - элементу,  содержащему фамилию.  <br/>
<span style="font-style: italic;"><br/>
</span>В  предыдущем примере (Листинг 3.2.1)<span style="font-weight: bold;">  </span>путь к выбираемому элементу "author/fio/f" можно сократить следующим образом: <br/>
<span style="font-weight: bold;">Листинг 3.2.3 </span><span style="font-weight: bold;"> (puschkin-family2.xsl)</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template match="author"&gt;
                &lt;html&gt;
                &lt;body&gt;
                &lt;h1&gt;
                    &lt;xsl:value-of select="fio/f"/&gt;
                &lt;/h1&gt;
                &lt;/body&gt;
                &lt;/html&gt;
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
В листинге 3.2.2  я задал инструкцию обработки входного XML  начиная от корневого узла  (<span style="font-style: italic;">xsl:template match="/"</span>), в листинге 3.2.4 обработка пошла от узла элемента "author" (<span style="font-style: italic;">xsl:template match="author"</span>). Соответственно изменилась и адресация в выборке ФИО автора. Внутри инструкции <span style="font-style: italic;">xsl:template</span>  работают относительные пути. Отсчет идет от  узла указаного в опции<span style="font-style: italic;"> match</span>. <br/>
                         </p>
<h3>3.3 Разбираемся с атрибутами</h3>
<p><span style="font-weight: bold;">3.3.1 Вывод атрибутов из XML</span><br/>
Теперь нужно вывести страну проживания А.С.Пушкина. Но адрес задан в атрибутах узла элемента "registry".  <br/>
&lt;registry country="Россия" city="Москва" /&gt;<br/>
Для того чтобы вывести страну  нужно применить ту же инструкцию, но в качестве параметра <span style="font-style: italic;">select</span> задается путь к  атрибуту, содержащему страну. <br/>
 <br/>
<br/>
<span style="font-weight: bold;">Листинг 3.3.1 (puschkin-family3.xsl)</span><br/>
   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">     &lt;xsl:template match="author"&gt;
                    &lt;html&gt;
                        &lt;body&gt;
                            &lt;h1&gt;
                                &lt;xsl:value-of select="fio/f"/&gt;
                            &lt;/h1&gt;
                            &lt;h2&gt;
                                &lt;xsl:value-of select="registry/@country" /&gt;
                            &lt;/h2&gt;
                        &lt;/body&gt;
                    &lt;/html&gt;
                &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Узел атрибута элемента (в данном случае элемента "registry"), является дочерним по отношению к самому элементу, поэтому появляется дополнительный слэш в пути.  Знак "@" перед именем "country", указывает что что это именно атрибут, а не другой элемент, который может быть вложен  в "registry" (например отдельные отметки в паспорте типа названия УВД, количества детей, жен и т.п. ). <br/>
<a name="332"/><br/>
<br/>
<span style="font-weight: bold;">3.3.2  Атрибуты HTML</span><br/>
<br/>
Предположим, что необходимо для JS-обработки вывести ID автора из элемента "author" в какой-нибудь HTML-тег, например в h1, чтобы получить такой код: <br/>
&lt;h1 id="author_id_1"&gt;Пушкин&lt;/h1&gt;<br/>
Это можно сделать двумя способами. Рассмотрим самый короткий и простой: <br/>
<br/>
<span style="font-weight: bold;">Листинг 3.3.2 </span><span style="font-weight: bold;">(puschkin-family3.xsl)</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template match="author"&gt;
            ...............................................
                &lt;h1 id="author_id_{@id}"&gt;
                    &lt;xsl:value-of select="fio/f"/&gt;
                &lt;/h1&gt;
            ...............................................
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Фигурные скобки указывают процессору, что нужно вывести содержимое указанное в пути. В примере указан путь к атрибуту "id" элемента "author".  Есть и другой способ, позволяющий определять атрибуты тегов как результат вычислений через элемент <span style="font-style: italic;">xsl:atribute</span>. Его я рассмотрю в следующей части. (*). </p>
<h3>3.  Копирование HTML-фрагментов.</h3>
<h4>3.1 Кошерное копирование xsl:copy-of</h4>
<p>Попробуем точно так же вывести содержимое элемента "text".  <br/>
<br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.4.1  (</span><span style="font-weight: bold;">copytext1.xsl)</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template match="author"&gt;
                &lt;html&gt;
                &lt;body&gt;
                &lt;h1&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/h1&gt;
                &lt;h2&gt;&lt;xsl:value-of select="registry/@country" /&gt;&lt;/h2&gt;   
                 &lt;div&gt;
                      &lt;xsl:value-of select="text"/&gt;
                 &lt;/div&gt;
                &lt;/body&gt;
                &lt;/html&gt;
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Вывести текст получилось, но не так как хотелось бы.   Инструкция <span style="font-style: italic;">xsl:value-of</span> съела все HTML-теги, содержащиеся в элементе text. Для того, чтобы выводить фрагмент HTML здеcь можно использовать команду <span style="font-style: italic;">xsl:copy-of, </span>которая выполняет буквальное копирование: <br/>
<br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.4.2  (</span><span style="font-weight: bold;">copytext2.xsl)</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template match="author"&gt;
                &lt;html&gt;
                &lt;body&gt;
                &lt;h1&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/h1&gt;
                &lt;h2&gt;&lt;xsl:value-of select="registry/@country" /&gt;&lt;/h2&gt;   
                 &lt;div&gt;
                      &lt;xsl:copy-of select="text"/&gt;
                 &lt;/div&gt;
                &lt;/body&gt;
                &lt;/html&gt;
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Вторая попытка тоже получилась криво.  Элемент "text" входного XML скопировался полностью и в HTML появился "левый" тег "text". А нам нужен не сам элемент, а только его содержимое  - элементы и текстовые узлы. Для этого опцию <span style="font-style: italic;">select </span> выбора <span style="font-style: italic;">xsl:copy-of </span> нужно изменить следующим образом:  <span style="font-style: italic;">select="text/*". </span>Если вы знаете как работать с командной строкой с файлами, то сразу увидите прямую аналогию. А если не умеете - вспомните что делает   в CSS селектор "*".  В обоих случаях так же как и в случае со "*"  в опции <span style="font-style: italic;">select</span> предлагается выбрать все узлы элемента "text" .  Листинг теперь выглядит так:<br/>
<span style="font-style: italic;"><br/>
</span><span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.4.3  (</span><span style="font-weight: bold;">copytext3.xsl)</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template match="author"&gt;
                &lt;html&gt;
                &lt;body&gt;
                &lt;h1&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/h1&gt;
                &lt;h2&gt;&lt;xsl:value-of select="registry/@country" /&gt;&lt;/h2&gt;   
                 &lt;div&gt;
                      &lt;xsl:copy-of select="text/*"/&gt;
                 &lt;/div&gt;
                &lt;/body&gt;
                &lt;/html&gt;
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Обратите внимание на то что при указании "*" выбираются именно узлы, а не элементы. Если забыли в чем разница, обязательно <a href="#root">вернитесь</a> и прочитайте <br/>
<br/>
Итак желаемый результат достигнут. Однако это далеко не все, что можно сделать при помощи XSLT . Если фрагмент HTML являетсям веллформенным XML, его можно преобразовать. Например - убрать ссылки или сделать эти ссылки невидимыми для поисковых машин, убрать пустые строки,  удалить отдельные теги и т.п. Но эта тема пока подождет, а пока лучше рассмотреть более часто употребимый,  но порицаемый способ вывода фрагментов HTML.</p>
<h4>3.2 Некошерное копирование xsl:value-of</h4>
<p>В <a href="#12">разделе 1.2</a> я говорил об обязательности валидного кода. Валидный код прекрасен, но  жизнь обычно вносит свои коррективы. Если приходится переделывать старый сайт, в котором сотни мегабайт контента сверстаны еще в прошлом веке, надеяться на валидность кода глупо. Попробовать перегонять все при помощи <a href="#" title="tidy.sourceforge.net/" rel="nofollow" class="external">Tidy</a>  в валидный xHTML  можно, но результат валидации сложной верстки мягко говоря предсказуем. Точнее заранее предсказуем - получится фигня.  В этом случае невалидный HTML загоняют в XML при помощи специального блока <a href="#" title="www.w3schools.com/xmL/xml_cdata.asp" rel="nofollow" class="external">CDATA</a>  <br/>
 </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;author id="1"&gt;
                     ..........................................................................
                    &lt;text&gt;
                     &lt;![CDATA[
                        Александр Сергеевич &lt;FONT SIZE="3" FACE="Courier New" COLOR="Magenta"&gt;Пушкин&lt;/font&gt;- наше все! &lt;p&gt;
                        Пушкин разбудил &lt;a href=http://en.wikipedia.org/wiki/Lermontov&gt;Лермонтова&lt;/a&gt;&lt;p&gt;       
                      ]]&gt;
                    &lt;/text&gt;
            &lt;/author&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Для того чтобы вывести этот блок как есть не взирая на невалидность  нужно использовать <span style="font-style: italic;">xsl:value</span>  со специальной опцией: <br/>
&lt;xsl:value-of select="text" disable-output-escaping="yes"/&gt;<br/>
<br/>
 </p>
<h3>3.5  Где в этом логика? xsl:if и xsl:choose</h3>
<p>Без условного оператора  обойтись никак не получается. В продвинутом шаблонизаторе он обязан быть, и в XSLT, как и в большинстве языков программирования, есть два способа обрабатки  условий</p>
<h4><span style="font-weight: bold;">3.5.1 </span>xsl:if  </h4>
<p>Предположим на странице автора нужно пометить тех кто усчастливился умереть до Октябрьской революции, от тех кому привелось жить при Советской Власти.  Для этого я буду проверять содержимое элемента rip в XML c  данными автора. При помощи вот такой конструкции:<br/>
<br/>
                   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:if test="rip &gt; 1917"&gt;
                   Советский поэт
            &lt;/xsl:if&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Если логическое выражение, содержащееся внутри опции <span style="font-style: italic;">test  </span>истинно, будут выполняться вложенные внутри xsl:if  инструкции процессору. В данном случае инструкций нет. Есть текст, который будет выведен как есть.  <br/>
С проверкой на несоветскость сложнее. Следующая конструкция  ошибочна<br/>
<br/>
                   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:if test="rip &lt;1917"&gt;
               Несоветский поэт
            &lt;/xsl:if&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Символ '&lt;' зарезервирован в xml, fа авторы XPATH не додумались ввести какую-нибудь удобную текстовую замену. Символ '&lt;' должен заменяться на известную вам сущность: '&amp;lt;' <br/>
<br/>
                   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:if test="rip &amp;lt; 1917"&gt;
                 Несоветский поэт
            &lt;/xsl:if&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
<span style="background-color: rgb(255, 255, 153);"><br/>
<br/>
<span style="background-color: rgb(255, 255, 255);">Ниже приводится полный текст:  </span><br/>
</span><br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.5.1  (</span><span style="font-weight: bold;">if.xsl)</span><br/>
 <br/>
   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template match="author"&gt;
                    &lt;html&gt;
                        &lt;body&gt;
                            &lt;h1&gt;
                                &lt;xsl:if test="rip &amp;gt; 1917"&gt;
                                    Советский поэт
                                &lt;/xsl:if&gt;
                                &lt;xsl:if test="rip &amp;lt;= 1917"&gt;
                                    Несоветский поэт
                                &lt;/xsl:if&gt;
                                &lt;xsl:value-of select="fio/f"/&gt;
                            &lt;/h1&gt;
                        &lt;/body&gt;
                    &lt;/html&gt;
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
 <br/>
<span style="background-color: rgb(255, 255, 153);"><span style="font-style: italic;">Отступление.</span><br/>
Как на самом деле, то как работает<span style="font-style: italic;"> xsl:if</span> - отдельная тема. Если вы работали  javascript, php и т.п.,  то должны быть в курсе,  что например результат  сравнения двух переменных в этих языках  не всегда является очевидным - все зависит от типа данных. Точно так же обстоит и с XPATH. Позже я напишу об этом более подробно.<br/>
</span> <br/>
<span style="font-style: italic;"> </span></p>
<h4><span style="font-weight: bold;">3.5.2 </span>  xsl:choose</h4>
<h4> <span style="font-weight: normal;">Пример из листинга 3.5.1 выполняет две проверки там где достаточно одной из-за того, что элементе <span style="font-style: italic;">if  </span>нет<span style="font-style: italic;"> else, </span>как в других языках программирования. Там где возникают сложные условия можно использовать другую инструкцию обработки условий   - <span style="font-style: italic;"> xsl:choose. <span style="font-weight: bold;"> </span></span>В качестве аналогии</span><span style="font-weight: normal;"> можно привести swich/case из  javascript и php. Но если в этих языках для прекращения действия оператора приходится ставить break (что меня страшно раздражает), в XSLT действие  <span style="font-style: italic;">xsl:choose </span>прекращается<span style="font-style: italic;"> </span>по выполнению первого условия. </span></h4>
<h4><span style="font-weight: normal;">Предыдущий пример с проставлением штампа <span style="font-style: italic;"> "</span>советский<span style="font-style: italic;">" </span> с применением  <span style="font-style: italic;">xsl:choose </span>будет выглядеть следующим образом:</span></h4>
<p><span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.5.2  (</span><span style="font-weight: bold;">choose.xsl)<br/>
<br/>
</span>   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template match="author"&gt;
                    &lt;html&gt;
                        &lt;body&gt;
                            &lt;h1&gt;
                                &lt;xsl:choose&gt;
                                    &lt;xsl:when test="born &gt; 1991"&gt;Постсоветский поэт&lt;/xsl:when&gt;
                                    &lt;xsl:when test="rip &amp;lt; 1917 "&gt;Несоветский поэт&lt;/xsl:when&gt;
                                    &lt;xsl:when test="(rip &gt;= 1917) and (rip &amp;lt; 1991)"&gt;Советский поэт&lt;/xsl:when&gt;
                                    &lt;xsl:otherwise&gt;Просто поэт&lt;/xsl:otherwise&gt;
                                &lt;/xsl:choose&gt;                          
                                &lt;span&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/span&gt;
                            &lt;/h1&gt;
                        &lt;/body&gt;
                    &lt;/html&gt;
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Первые две проверки практически не отличаются от примера в листинге 3.5.2   А в третьей проверке я усложнил условие и ввел логическую операцию "И" ("and")  Естественно что в  XSLT присутствует полный набор логических операций ("and", "or", "not").  <br/>
Элемент<span style="font-style: italic;"> xsl:otherwise</span> - финальный. Все инструкции вложенные в него  выполняются если ни одно из предыдущих условий не выполнено. <br/>
</p>
<h3>3.6  Зацикливаемся. xsl:for-each</h3>
<p>Любой традиционный язык программирования немыслим без операторов цикла. В XSLT похожая конструкция тоже присутствует.  Я не случайно написал "похожая".  Она похожа на  обычные операторы цикла, к которым вы привыкли,  очень отдаленно. Отдаленно <span style="font-style: italic;">xsl:for-each </span> напоминает foreach в php или for в javascript<span style="font-style: italic;">, </span>когда требуется перебор свойств объекта. Что-то  типа: <br/>
<br/>
&lt;script language="JavaScript" type="text/javascript"&gt; <br/>
for (i in document) {....}<br/>
&lt;/script&gt;<br/>
<br/>
Рассмотрим пример вывода списка всех авторов, используя новый XML-документ: <br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.6.1  (</span><span style="font-weight: bold;">authors.xml)</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;authors&gt;
                &lt;author id="1"&gt;
                    &lt;fio&gt;
                        &lt;f&gt;Пушкин&lt;/f&gt;
                        &lt;i&gt;Александр&lt;/i&gt;
                        &lt;o&gt;Сергеевич&lt;/o&gt;
                    &lt;/fio&gt;
                    &lt;born&gt;1799&lt;/born&gt;
                &lt;/author&gt; 
                &lt;author id="2"&gt;
                    &lt;fio&gt;
                        &lt;f&gt;Лермонтов&lt;/f&gt;
                        &lt;i&gt;Михаил&lt;/i&gt;
                        &lt;o&gt;Юрьевич&lt;/o&gt;            
                    &lt;/fio&gt;
                    &lt;born&gt;1814&lt;/born&gt; 
                &lt;/author&gt; 
            ...............................................................
            ...............................................................
            ...............................................................
            ...............................................................
            &lt;/authors&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
<br/>
<span style="font-weight: bold;"><br/>
</span><br/>
Необходимо сформировать такой список:</p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;table&gt;
                &lt;tr&gt;&lt;td&gt;1799&lt;/td&gt;&lt;td&gt;&lt;a href="author1.htm"&gt;Пушкин А.С.&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
                ............................................................................
                &lt;tr&gt;&lt;td&gt;1703&lt;/td&gt;&lt;td&gt;&lt;a href="author7.htm"&gt;Кантемир А.Д.&lt;/td&gt;&lt;/tr&gt;
            &lt;/table&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Вот как будет выглядеть xslt-шаблон для обработки этого XML:<br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.6.2  (</span><span style="font-weight: bold;">foreach.xsl)</span><br/>
   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template match="authors"&gt;
                    &lt;html&gt;
                        &lt;body&gt;
                        &lt;table&gt;
                            &lt;xsl:for-each select="author"&gt;
                            &lt;tr&gt;
                                &lt;td&gt;&lt;xsl:value-of select="born"/&gt;&lt;/td&gt;
                                &lt;td&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/td&gt;
                            &lt;/tr&gt;
                            &lt;/xsl:for-each&gt;    
                        &lt;/table&gt;
                        &lt;/body&gt;
                    &lt;/html&gt;
                &lt;/xsl:template&gt;
            &lt;/xsl:stylesheet&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
В этом примере  <span style="font-style: italic;"> xsl:for-each</span> организует перебор всех элементов "author". Далее все что находится внутри этого этого элемента адресуется относительно текущего элемента "author", заданного в опции <span style="font-style: italic;">select  </span>инструкции <span style="font-style: italic;">xsl:for-each</span>  Поэтому для вывода значения года рождения, заданного элементом с именем "born"  используется конструкцию: <br/>
&lt;xsl:value-of select="born"/&gt;<br/>
Для вывода ФИО поэта используется конструкция <br/>
&lt;xsl:value-of select="fio/f"/&gt;<br/>
<br/>
Можно усложнить задачу и пронумеровать строки.  Модифицируем предыдущий (Листинг 3.6.2 ) пример <br/>
  <br/>
  <span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.6.2  (</span><span style="font-weight: bold;">foreach2.xsl)</span> </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">.....................................................................................
             &lt;table&gt;
                            &lt;xsl:for-each select="author"&gt;
                         &lt;tr&gt;
                                &lt;td&gt;&lt;xsl:value-of select="position()"/&gt;&lt;/td&gt; 
                                &lt;td&gt;&lt;xsl:value-of select="born"/&gt;&lt;/td&gt;
                                &lt;td&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/td&gt;
                        
                            &lt;/tr&gt;
                            &lt;/xsl:for-each&gt;    
             &lt;/table&gt;
            ................................................................................</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Здесь в первой строке появляется незнакомая конструкция position(). Как несложно догадаться это функция,  определяющая позицию текущего элемента. В данном случае элемента rec в списке авторов. Это одна из функций языка XPATH. По сравнению с традиционными языками программирования перечень функций не очень большой. В нем есть минимальный набор  строковых, арифметических и логических  функций, функции преобразования типа, а так же специфические для XSLT/XPATH функции работы с деревьями. Полный список этих функций можно посмотреть в <a href="#add1">приложении 1</a>. !!!<br/>
<br/>
Еще раз хотелось бы подчеркнуть, что цикл с использованием  <span style="font-style: italic;">xsl:for-each </span>позволяет только перебрать имеющиеся элементы. Повторить некоторую операцию заданное число раз при помощи <span style="font-style: italic;">xsl:for-each,</span> как это делают арифметические операторы цикла в javascript или php, вообще говоря невозможно.  Для этого в XSLT существуют другие способы. Но они не вполне тривиальные.  <br/>
<br/>
Поскольку, я уже упомянул  встроенную функцию<span style="font-weight: bold;"> </span><span style="font-style: italic;">position(), </span>трудно не рассмотреть  классическую задачу верстки - раскраску таблицы "зеброй". Каждая четная строка - должна быть покрашена одним цветом, а нечетная - другим.. Заодно    выведем список авторов с ссылками на страницы авторов. На выходе преобразования должно получиться следующее: </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;table&gt;
                &lt;tr class="color0"&gt;&lt;td&gt;1799&lt;/td&gt;&lt;td&gt;&lt;a href="author/1"&gt;Пушкин А.С.&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
                &lt;tr class="color1"&gt;&lt;td&gt;1814&lt;/td&gt;&lt;td&gt;&lt;a href="author/2"&gt;Лермонтов М.Ю.&lt;/td&gt;&lt;/tr&gt;
                &lt;tr class="color0"&gt;&lt;td&gt;1814&lt;/td&gt;&lt;td&gt;&lt;a href="author/3"&gt;Фет А.А.&lt;/td&gt;&lt;/tr&gt;
                &lt;tr class="color1"&gt;&lt;td&gt;1905&lt;/td&gt;&lt;td&gt;&lt;a href="author/4"&gt;Хармс Д.&lt;/td&gt;&lt;/tr&gt;
                ............................................................................
                
            &lt;/table&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
 Число в адресе ссылки должно соответствовать атрибуту id автора (<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.6.1</span>), а класс color0 и color1 - цветам четных и нечетных строк.<br/>
<br/>
Шаблон для такого преобразования будет следующим: <br/>
  <br/>
  <span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.6.2  (</span><span style="font-weight: bold;">foreach3.xsl)</span> <br/>
<br/>
   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template match="authors"&gt;
                    &lt;html&gt;
                        &lt;body&gt;
                            &lt;table&gt;
                                    &lt;xsl:for-each select="author"&gt;
                                        &lt;tr class="color{position() mod 2}"&gt;
                                            &lt;td&gt;&lt;xsl:value-of select="position()"/&gt;&lt;/td&gt;
                                            &lt;td&gt;&lt;xsl:value-of select="born"/&gt;&lt;/td&gt;
                                            &lt;td&gt;&lt;a href="/author/{@id}"&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/a&gt;&lt;/td&gt;
                                                  
                                        &lt;/tr&gt;
                                    &lt;/xsl:for-each&gt;   
                         &lt;/table&gt; 
                        &lt;/body&gt;
                    &lt;/html&gt;
                
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Нового здесь почти ничего нет. Для формирования   адреса в ссылке и класс, определяющего цвет строки используется тот же прием что и в разделе <a href="#332">3.3.2  (Атрибуты HTML)</a><span style="font-weight: bold;">,</span> а для    того чтобы задать четность используется арифметическое выражение деления по модулю 2 позиции элемента:<br/>
 <span style="font-style: italic;">(position() mod 2)<br/>
</span>Результат деления   по модулю 2 равен<span style="font-style: italic;"> </span>0 для четных позиций и 1 для нечетных. <span style="font-style: italic;"><br/>
</span><span style="font-weight: bold;"> <br/>
</span></p>
<h3>3.7  Наводим порядок. xsl:sort</h3>
<p>В предыдущем разделе порядок вывода списка авторов повторяет порядок следования их в xml (Листинг 3.6.1).  Порядок достаточно произвольный, а для реального сайта необходимо, чтобы данные были упорядочены по алфавиту,  дате рождения или каким-то другим способом. Для сортировки служит элемент <span style="font-style: italic;">xsl:sort. </span>С его использованием модификация примера (Листинг 3.6.2 )  будет выглядеть так: <br/>
<br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.7.1  (</span><span style="font-weight: bold;">sort1.xsl)</span><br/>
           </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;table&gt;
                    &lt;xsl:for-each select="author"&gt;
                            &lt;xsl:sort select="born"/&gt;    
                            &lt;tr&gt;
                                &lt;td&gt;&lt;xsl:value-of select="position()"/&gt;&lt;/td&gt; 
                                &lt;td&gt;&lt;xsl:value-of select="born"/&gt;&lt;/td&gt;
                                &lt;td&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/td&gt;
                            &lt;/tr&gt;
                    &lt;/xsl:for-each&gt;  
            &lt;/table&gt;</pre><!--/php--></td></tr></table>
<p><span style="font-style: italic;"><br/>
</span><br/>
Опция <span style="font-style: italic;">select  э</span>лемента<span style="font-style: italic;"> </span>  <span style="font-style: italic;">xsl:sort</span>  определяет по какому ключу идет сортировка. В примере - по дате рождения. Наверное еще раз надо повторить - внутри элемента <span style="font-style: italic;">xsl:for-each</span>  действует относительная адресация. Т.е. отсчет идет от текущего элемента "author",  а символ "@" указывает на то что выбирается атрибут элемента author.  Если же надо упорядочить по имени автора, элемент сортировки должен выглядеть так: <br/>
&lt;xsl:sort select="."/&gt;<br/>
В XPATH  <span style="font-style: italic;">select="."</span> означает выборку текущего элемента. В данном случае содержимое элемента - ФИО автора, и по нему производится сортировка. <br/>
Элемент<span style="font-style: italic;"> xsl:sort </span>имеет  дополнительные параметры: порядок сортировки ( убывание/возрастание), тип данных (числовой/текстовый) и др. <br/>
см. примеры на  zvon.org [<a href="#" title="zvon.org/xxl/XSLTutorial/Output_rus/21.htm" rel="nofollow" class="external">1</a>] [<a href="#" title="zvon.org/xxl/XSLTutorial/Output_rus/20.htm" rel="nofollow" class="external">2</a>] [<a href="#" title="zvon.org/xxl/XSLTutorial/Output_rus/19.htm" rel="nofollow" class="external">3</a>]  </p>
<h3>3.7  Процедурный кабинет. xsl:call-template и xsl:import</h3>
<p>В предыдущих разделах я сделал шаблоны для вывода списка авторов и страницы автора. При наличии данных, можно было бы сделать относительно полноценный сайт.  Но полноценному сайту не хватает   копирайта, логотипа, CSS,  метатегов и всякой бесполезной ерунды, типа  счетчика Рэмблера. Добавим  эти бебехи в шаблон списка авторов (модификация Листинга 3.6.2)<br/>
<br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.7.1  (</span><span style="font-weight: bold;">index0.xsl)<br/>
<br/>
</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
            &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
                &lt;xsl:template match="authors"&gt;
                    &lt;html&gt;
                        &lt;head&gt;
                            &lt;title&gt;Поэтический портал&lt;/title&gt;
                            &lt;meta  name="generator"  content="XSLT" /&gt;
                            &lt;meta name="Yandex" content="Люби меня как я тебя!" /&gt;
                            &lt;link rel="stylesheet" href="D:/WEB/aps/zpsy/js/RTE/screen.css" type="text/css" /&gt;
                        &lt;/head&gt;
                              
                        &lt;body&gt;
                            &lt;div id="header"&gt;&lt;img src="logo.jpg" alt="Логотип сайта" /&gt;&lt;/div&gt;
                            &lt;table&gt;
                                &lt;xsl:for-each select="author"&gt;
                                    &lt;tr&gt;
                                        &lt;td&gt;&lt;xsl:value-of select="born"/&gt;&lt;/td&gt;
                                        &lt;td&gt;&lt;a href="/author/{@id}"&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/a&gt;&lt;/td&gt;
                                    &lt;/tr&gt;
                                &lt;/xsl:for-each&gt;   
                            &lt;/table&gt;
                            &lt;div id="footer"&gt;
                                (c) Исаак Тынгылчав
                                &lt;img src="http://rambler/блаблабла"  alt="Rambler Top100" /&gt;
                            &lt;/div&gt;
                        &lt;/body&gt;
                    &lt;/html&gt;
                &lt;/xsl:template&gt;
                
            &lt;/xsl:stylesheet&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Этот шаблон применительно к authors.xml выведет  список авторов в формате блога. <br/>
<br/>
Аналогичную модификацию шаблона страницы автора  (Листинг 3.5.2 )  я не привожу. В архиве он называется author.xsl и применяется к pushkin.xml<br/>
<br/>
Рассматривая оба шалона, можно обнаружить явные излишества - одни и те же элементы присутствуют дважды.  При этом они содержат совершенно одинаковые данные. Копипаст в таких случаях не только  не нужен, но и вреден. Для его устранения  в традиционных языках программирования как правило используются процедуры. Похожий механизм есть и в XSLT. Он носит название "именованные шаблоны".  Сразу создадим отдельный библиотечный файл lib.xsl  Этот файл будет содержать описание процедур (именованных шаблонов), отвечающих за вывод общих для  index.xsl и author.xsl фрагментов HTML-кода: <br/>
<br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.7.2  (</span><span style="font-weight: bold;">lib.xsl)</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
                &lt;xsl:template name="head"&gt;
                    &lt;head&gt;
                        &lt;title&gt;Поэтический портал&lt;/title&gt;
                        &lt;meta  name="generator"  content="XSLT" /&gt;
                        &lt;meta name="Yandex" content="Люби меня как я тебя!" /&gt;
                        &lt;link rel="stylesheet" href="D:/WEB/aps/zpsy/js/RTE/screen.css" type="text/css" /&gt;
                    &lt;/head&gt;              
                &lt;/xsl:template&gt;
            
                &lt;xsl:template name="header"&gt;
                    &lt;div id="header"&gt;&lt;img src="logo.jpg" alt="Логотип сайта" /&gt;&lt;/div&gt;           
                &lt;/xsl:template&gt;
            
                
                &lt;xsl:template name="footer"&gt;
                    &lt;div id="footer"&gt;
                        (c) Исаак Тынгылчав
                        &lt;img src="http://rambler/блаблабла"  alt="Rambler Top100" /&gt;
                    &lt;/div&gt;
                &lt;/xsl:template&gt;  
            
            &lt;/xsl:stylesheet&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Для того, чтобы подгрузить этот библиотечный файл в index.xsl и authors.xsl после инструкции <span style="font-style: italic;">xsl:stylesheet </span>нужно добавить строку: <br/>
 </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:import href="lib.xsl"/&gt;</pre><!--/php--></td></tr></table>
<p><br/>
Наверное было бы лишним проводить прямую аналогию с инструкцией @import в CSS или include в php <br/>
<br/>
Вызов же процедур (именованных шаблонов) в index.xsl и authors.xsl  выглядит так: <br/>
 </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:call-template name="head" /&gt;
             &lt;xsl:call-template name="footer" /&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
В том месте xslt-шаблона, где будет произведен вызов именованных шаблонов  head и footer  будет произведен вывод содержащихся в них фрагментов HTML-кода.  <br/>
<br/>
Листинг 3.7.1 c с использованием процедур - именованных шаблонов  будет переписан в виде: <br/>
   <br/>
<br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.7.2  (</span><span style="font-weight: bold;">index2.xsl)<br/>
<br/>
</span></p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
            &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
             &lt;xsl:import href="lib.xsl"/&gt;
                &lt;xsl:template match="authors"&gt;
                    &lt;html&gt;
                         &lt;xsl:call-template name="head" /&gt;
                        &lt;body&gt;
                         &lt;xsl:call-template name="header" /&gt;
                            &lt;table&gt;
                                &lt;xsl:for-each select="author"&gt;
                                    &lt;tr&gt;
                                        &lt;td&gt;&lt;xsl:value-of select="born"/&gt;&lt;/td&gt;
                                        &lt;td&gt;&lt;xsl:value-of select="fio/f"/&gt;&lt;/td&gt;
                                    &lt;/tr&gt;
                                &lt;/xsl:for-each&gt;   
                            &lt;/table&gt;
                            &lt;xsl:call-template name="footer" /&gt;
                        &lt;/body&gt;
                    &lt;/html&gt;
                &lt;/xsl:template&gt;
             &lt;/xsl:stylesheet&gt;</pre><!--/php--></td></tr></table>
<p><br/>
<br/>
Аналогичную операцию со страницей автора вы можете сделать самостоятельно, но если лениво - смотрите файл author2.xsl<br/>
На этом можно было бы пока и закончить, но процедура без  параметров выглядит немного странно.  В XSLT  точно так же как и в традиционных языках в процедуры (именованные шаблоны) можно передавать параметры. Рассмотрим на примерах  страниц index2.xsl и author2.xsl <br/>
<br/>
Очевидно, что заголовки title страниц должны быть уникальными. В примерах с применением шаблонов author2.xsl и index2.xsl они  общие для всего сайта что совершенно неправильно. Для того чтобы передать параметры в процедуру ее описание должно быть следующим: <br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.7.3</span><br/>
   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template name="head"&gt;
                 &lt;xsl:param name="title"&gt;Поэтический портал &lt;/xsl:param&gt;
                    &lt;head&gt;
                        &lt;title&gt;&lt;xsl:value select="$title" /&gt;&lt;/title&gt;
                        ........................................................................
                        ........................................................................
                        ........................................................................
                    &lt;/head&gt;              
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
Или в сокращенной форме:<br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.7.3</span><br/>
   </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:template name="head"&gt;
                 &lt;xsl:param name="title" select="Поэтический портал"/&gt;
                 ......................................................................................        
                 ......................................................................................        
                 ......................................................................................        
            &lt;/xsl:template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
Наличие передаваемого параметра определяется инструкцией<span style="font-style: italic;"> xsl:param</span>. В опции этой инструкции <span style="font-style: italic;">select</span>  задается значение параметра по умолчанию (если вы знакомы с  PHP,  вам это понятие должно быть знакомо). Если производится вызов  процедуры (именованного шаблона) <span style="font-style: italic;">xsl:call-template</span>   без указания параметра, его значение будет равно значению по умолчанию.<br/>
Для того чтобы вывести значение праметра используется знакомая инструкция xsl:value. Имени параметра в опции <span style="font-style: italic;">select </span>должен прешествовать знак доллара<span style="font-style: italic;">. <br/>
</span> <br/>
Для главной страицы содержимое title фиксированно, так как страница уникальна. И оно может быть введено в качестве title, которое будет по умолчанию ставится на всех несущественных страницах сайта.  А вот для страницы автора содержимое title должно содержать имя автора. Это данные из  входного XML. Если забыли - откатитесь в раздел 3.2 и посмотрте как выглядел XML и XSLT. Формирование параметра для title на странице автора будет выглядеть так:<br/>
<span style="font-weight: bold;">Листинг </span><span style="font-weight: bold;">3.7.4</span><br/>
               </p>

<table class="code"><tr><td><!--php--><pre class="brush: plain">&lt;xsl:call-template name="head" &gt;
                                &lt;xsl:with-param name="title"&gt;
                                    &lt;xsl:value-of select="fio/f"/&gt;. Биография.
                                &lt;/xsl:with-param&gt;
              &lt;/xsl:call-template&gt;</pre><!--/php--></td></tr></table>
<p><br/>
Кроме  инструкции  <span style="font-style: italic;">xsl:import</span> существует аналогичная инструкция <span style="font-style: italic;">xsl:include </span> их отличия в правилах разрешения конфликтов, в случае если одному и тому же узлу соответствуют несколько правил обработки с одинаковым приоритетом.    </p>
<h3>3.8  Заключение </h3>
<p>На этом раздел   можно закончить.  Полученной информации достаточно чтобы сверстать среднестатистический сайт - персональный блог, несложный интернет-магазин и т.п.  Сверстанные в таком стиле шаблоны мало чем отличаются  от традиционных PHP-шаблонизаторов.  Но это очень ограниченный стиль программирования, в котором от XSLT-шаблонов почти ничего нет.  В следующем разделе я постараюсь объяснить именно ту специфику работы с шаблонами, которая отличает ее от всех прочих шаблонизаторов. <br/>
<br/>
<br/>
ПРОДОЛЖЕНИЕ  СЛЕДУЕТ</p></div>
          <ol class="tags big">
            <li class="date">2009-11-27</li>
            <li>
              <a href="/short_course_for_html-coder">short_course_for_html-coder</a>
            </li>
          </ol>
          <ol class="see">
            <li>
              <a href="#"><span>Примеры к тексту</span> - <b>erum.ru/doc/xslt_for_beginners.zip</b></a>
            </li>
            <li>
              <a href="#"><span>zvon.org/xxl/XSLTutorial/Output_rus/index.htm</span> - <b>XSLT в примерах (zvon.org)</b></a>
            </li>
          </ol>
          <ul class="comment">
            <li id="a372" title="a0">
              <a name="&#x414;&#x44B;&#x43C;&#x43E;&#x441;" title="" rel="28.11.09"/>
              <div>Баги в верстке. Картинки пропали и ссылки с якорями ведут на локальный диск. <br/>Но интересно. Обязательно почитаю как будет время.</div>
            </li>
            <li id="a373" title="a0">
              <a name="&#x414;&#x44B;&#x43C;&#x43E;&#x441;" title="" rel="28.11.09"/>
              <div>Самое главное - архива с исходниками нет.</div>
            </li>
            <li id="a374" title="a373">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="28.11.09"/>
              <div>Спасибо. Постараюсь исправить в ближайшее время.</div>
            </li>
            <li id="a375" title="a0">
              <a name="Le capitaine Nemo" title="" rel="29.11.09"/>
              <div>Спасибо. Давно искал что-то попроще. <br/>Что-нибудь можете сказать про книгу Тидуэлла XSLT <a title="http://www.books.ru/shop/books/704252" rel="nofollow" class="external" href="#">ссылка</a>  <br/>Стоит покупать?</div>
            </li>
            <li id="a376" title="a375">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="29.11.09"/>
              <div>Ничего не скажу. Не видел. <br/>Но если собираетесь всерьез заниматься XSLT - то лучше взять. Все-таки нормальный систематический учебник нужен.Других учебников в продаже все равно не найти.</div>
            </li>
            <li id="a377" title="a0">
              <a name="&#x42F;&#x43C;&#x430;&#x43B;" title="" rel="29.11.09"/>
              <div>Странный подход. Вместо того чтобы объяснить все преимущиства вы объясняете как неэффективно работать.<br/>Назвать это кратким курсом тоже нельзя.</div>
            </li>
            <li id="a378" title="a377">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="29.11.09"/>
              <div>Может быть вы правы. <br/>Но в болталках все время болтают, о том что XSLT нормальный верстальщик освоить не может. Я с этим отчасти согласен. Средний верстальщик скорее удавится, чем выучит по книге Валикова или спецификации XSLT. <br/>Мне немного приходилось обучать верстальщиков XSLT. В том порядке в котором все написано я и обучал. От простого к сложному. От знакомых конструкций к незнакомым. Это имхо нормальная методика.</div>
            </li>
            <li id="a379" title="a376">
              <a name="tonik" title="" rel="29.11.09"/>
              <div>Стоит !!! Покупайте эту книжку !!! Норм литературы по XSLT на русском не найти!!! Эта книга как справочник не заменима</div>
            </li>
            <li id="a380" title="a375">
              <a name="&#x41B;&#x43E;&#x445;&#x430;&#x43D;&#x43A;&#x438;&#x43D;" title="" rel="29.11.09"/>
              <div><a title="http://www.obuk.ru/compbook/11275-kholzner-s.-xslt-biblioteka-programmista.html" rel="nofollow" class="external" href="#">ссылка</a>  <br/>Скачай Холзнера - самый лучший учебник, какой есть. Остальное - отстой. <br/>Ну как справочник в крайней мере. Но учебник - только Холзнер.</div>
            </li>
            <li id="a381" title="a380">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="29.11.09"/>
              <div>Кстати да. В качестве учебника Холзнер - действительно лучший из того что видел. Но в бумажной версии его не достать. <br/>А Тидуэла не смотрел. Сказать ничего не могу.</div>
            </li>
            <li id="a382" title="a0">
              <a name="&#x421;&#x435;&#x440;&#x433;&#x435;&#x439;" title="seriyps.ru" rel="30.11.09"/>
              <div>Для этого опцию select  выбора xsl:copy-of  нужно изменить следующим образом:  select="text/*".<br/>Ойкласс! Вот про звездочку в конце сам не допер, долго мучался как корневой тег не выводить... Даже не помню как разрулил этот момент<br/>А вообще очень полезная статья, жду продолжения!</div>
            </li>
            <li id="a384" title="a0">
              <a name="&#x410;&#x43D;&#x442;&#x43E;&#x445;&#x430;" title="" rel="02.12.09"/>
              <div>Здорово. Хорошо пишешь. Мне Валикова дали почитать - такая мутота, блевать хочется. У тебя понятно все разжевано. <br/>Только в нкоторых примерах ошибки. Там где проциклы. <br/>Продолжение когда будет?</div>
            </li>
            <li id="a385" title="a384">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="02.12.09"/>
              <div>Когда будет продолжение - не знаю. Написано давно. Нужно сидеть и редактировать. <br/>Ошибку посмотрю. Жаль, что конкретно не указали где именно и какая.</div>
            </li>
            <li id="a386" title="a384">
              <a name="Le capitaine Nemo" title="" rel="02.12.09"/>
              <div>Использовать Валиков в качестве учебника нельзя, но когда освоишь азы, ее нужно обязательно перечитать. Там много очень важного. И много такого которое обязательно нужно знать, но здесь этого нет.</div>
            </li>
            <li id="a387" title="a386">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="02.12.09"/>
              <div>Присоединяюсь к тому что здесь очень многого нет и обязательно нужно читать какой-нибудь нормальный учебник  или справочник. Но Валиков - это действительно жестоко.</div>
            </li>
            <li id="a389" title="a377">
              <a name="Le capitaine Nemo" title="" rel="04.12.09"/>
              <div>Присоединяюсь.<br/>Складывается такое впечатление, что автор статьи очень поверхностно знает XSLT. Уровню знания соответствует и уровень изложения.<br/>Выплеснул самое главное, то из-за чего XSLT все его применяют. <br/>Вот так!</div>
            </li>
            <li id="a394" title="a0">
              <a name="Le capitaine Nemo" title="" rel="07.12.09"/>
              <div>Спасибо за хорошую стать. Давно искал что-то доступное по этой теме. Продолжение когда будет и что там будет?</div>
            </li>
            <li id="a395" title="a394">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="07.12.09"/>
              <div>Спасибо. <br/>Когда будет вторая часть - не знаю. Написано пости год назад, но времени и сил сесть за редактирование нет. <br/>Во второй части подробно разжевано: xpath, работа с шаблонными правилами, функции и основные приемы работы.</div>
            </li>
            <li id="a396" title="a389">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="07.12.09"/>
              <div>Самое главное должно быть во второй части. Подождите пока я опубликую материал полностью. Может быть ваше отношение несколько изменится. Буду признателен за более конкретные замечания</div>
            </li>
            <li id="a397" title="a0">
              <a name="&#x410;&#x43C;&#x438;&#x440;" title="" rel="08.12.09"/>
              <div>Замечания:<br/>У вас  стоит ссылка на книгу Валикова. Она не работает. Скачать можно полномью здесь: <br/><a title="http://arhivknig.com/programming/web-design/48860-tekhnologija-xslt.html" rel="nofollow" class="external" href="#">ссылка</a>  <br/>Триальный Oxygen работает месяц. Затем можно переинсталировать и еще месяц пользоваться.<br/>Статья у вас очень хорошая, не слушайте тролей. Мне уже не сильно нужно, но если бы полгода назад нашел ее сильно жизнь облегчило бы.</div>
            </li>
            <li id="a398" title="a0">
              <a name="GiN" title="" rel="10.12.09"/>
              <div>Прекрасная статья. Уже, конечно, хотелось бы продолжение почитать.</div>
            </li>
            <li id="a399" title="a0">
              <a name="ATimofeev" title="www.atimofeev.ru" rel="11.12.09"/>
              <div>НАЙТИ книги, перечисленные ниже, НАЙТИ в печатном виде невозможно</div>
            </li>
            <li id="a402" title="a0">
              <a name="Placebo" title="" rel="14.12.09"/>
              <div>Автор, вы очень хорошо пишете. Но нерегулярно :) <br/>Очень хочется дождаться продолжения в обозримый период времени. Пожалуйста</div>
            </li>
            <li id="a420" title="a0">
              <a name="Echo" title="" rel="24.12.09"/>
              <div>Исаак, у вас сайт разъезжается в Хроме. Поправьте.</div>
            </li>
            <li id="a421" title="a420">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="" rel="24.12.09"/>
              <div>Когда-нибудь, поправлю. Сейчас времени на это нет. <br/>Я этот сайт сверстал года три назад. Не было тогда Хрома. Под остальными вроде ходит.</div>
            </li>
            <li id="a424" title="a0">
              <a name="&#x421;&#x43C;&#x438;&#x43B;&#x430;&#x434;&#x43E;&#x43D;" title="evafobia.ru" rel="02.01.10"/>
              <div>Часть перечисленных книг есть в P2P сетях.</div>
            </li>
            <li id="a455" title="a0">
              <a name="s_s" title="samizdam.spb.ru" rel="20.02.10"/>
              <div>хорошая статья, наконец-то начинает получаться что-то из манипуляций с xml+xsl=xhtml. )))</div>
            </li>
            <li id="a469" title="a0">
              <a name="Le capitaine Nemo" title="" rel="14.03.10"/>
              <div>Спасибо большое. Не знал с какой стороны подойти к изучению вопроса. Прочитал статью - узнал общее, теперь буду изучать частное.<br/>Холзнер есть на progbook.</div>
            </li>
            <li id="a476" title="a0">
              <a name="RedCat" title="" rel="22.03.10"/>
              <div>Спасибо за статьи. Туман в голове начал немного рассеиваться.  <br/>Не подскжете есть ли курсы в Москве по XSLT? Куда стоит сходить?</div>
            </li>
            <li id="a477" title="a476">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="22.03.10"/>
              <div>Спасибо. <br/>Про курсы ничего не скажу. Самого когда-то посылали на курсы "Специалист" при Бауманском. Достаточно бестолковое было занятие. Почему-то все крутилось вокруг MS и половину курса объясняли что такое HTML.</div>
            </li>
            <li id="a554" title="a396">
              <a name="Suiliand" title="" rel="22.08.10"/>
              <div>Зря вы так, автор молодец, пусть простенько написано, но для начальных знаний очень хорошо. Есть на чем поэкспериментировать, а читать качественный учебник или справочник чревато тем что любовь к xslt будет отбита очень на долго/ По крайней мере для тех кто постигает все через руки очень хороший курс.</div>
            </li>
            <li id="a595" title="a0">
              <a name="folibis" title="" rel="20.01.11"/>
              <div>в Листинге 3.4.3<br/>инструкция<br/>не выводит половину текста, того что не обрамлен каким то тегом, правильно так:</div>
            </li>
            <li id="a596" title="a477">
              <a name="Le capitaine Nemo" title="" rel="20.01.11"/>
              <div>эээ ... съелись теги, короче<br/>вместо text/*<br/>надо text/node()</div>
            </li>
            <li id="a600" title="a0">
              <a name="orendzi" title="" rel="20.02.11"/>
              <div>спасибо, очень помогла твоя статья =)))</div>
            </li>
            <li id="a691" title="a0">
              <a name="Merkyrio" title="" rel="01.02.12"/>
              <div>Отличный материал для того что бы наконец то с чего то начать. До этого прочитал десяток похожих, только в этой нашел понятную терминологию и объяснение непонятных моментов. Спасибо автору</div>
            </li>
          </ul>
        </div>
      </div>
      <div class="R">
        <a href="/" title="&#x41D;&#x430; &#x433;&#x43B;&#x430;&#x432;&#x43D;&#x443;&#x44E;"/>
      </div>
    </div>
    <div id="li"/>
  </body>
</html>

