Как стать автором
Обновить

Комментарии 30

Занятно, но все таки без знаний xslt многим людям это ни о чем не скажет (: Хотелось бы чууууточку подробнее
Честно говоря, для тех, кто знает xslt, здесь тоже нет ничего особенного :)
А какой смысл смотреть блог по XSLT не зная оного?
А какой смысл читать книги по программированию не зная программирования? (:

Чтобы научиться, узнать что-то новое. XSLT знаю только в теории, на практике ни разу не удалось использовать.
Хотя возможно вы и правы (:

Чтоб узнать, очевидно же
Чтобы узнать язык\технологию существуют книги, у каждого языка\технологии есть свои маститые авторы. Я думаю начинать нужно именно с книг. Хабр мне видется как сборник статей по продвинутым и\или велосипедным решениям людей, а не прописных истин о которых можно прочесть в любом справочнике по языку\технологии.
И по книгам, и по форумам, и гугл в помощь, и блоги тоже. Чтение человеком блога по теме показывает его заинтересованность. Конечно часть постетителей — новички, мне это тоже порой досаждает, а порой веселит.

> Хабр мне видится как…
Хабр так устроен, что регулируется количеством, а не качеством, а потому в нём всегда будут статьи для среднего уровня и ниже среднего. Чтоб остались только профи — должно прилететь НЛО и порезать флуд.
XSL это всего лишь таблица стиля и шаблона для форматирования XML-документа. Ничего сверхсложного тут нет :)
XSL чрезвычайно гибкая вещь, и она действительно кажется простой, пока не найдётся человек со сложными задачами и сложными решениями.
Писать простые, понятные и функциональные шаблоны очень сложно.
Ничего тут сложного нет, достаточно хорошо знать XSLT и алгоритмизацию) Красивые и простые конечно поначалу получаться не будут, но это все вопрос времени.
Утверждение «в технологии %% нет ничего сложного, если ее хорошо знать» верно в абсолютном большинстве случаем.
xslt достаточно запутана, если приходится делать какие то действительно сложные преобразования, особенно если нет желания/возможности по каждому чиху дергать экстеншены. В посте простейший пример, но когда счет идет на десятки тысяч строк, начинаешь ненавидеть эту технологию
Сказать фразу «но когда %%, начинаешь ненавидеть эту технологию» можно о чем угодно. Чем задача сложнее, тем она интересней. В это суть программирования и алгоритмизации в принципе, не так ли?
М.б. лучше все-же с азов?
Если действительно заинтересовало, попробуйте почитать Стивена Холзнера. Книга написана предельно доступным языком, в отличие от многих других. К сожалению в магазинах ее купить нельзя — она издавалась давно и микроскопическим тиражом. Но есть в электронном виде: www.maxbit.ru/library/it/xslt/16-xslt-biblioteka-programmista.html
Дарья, благодарю за статью :)
Подскажите, как можно при XSL-трансформации упорядочивать элементы списка, например, поменять местами категории AMD и Intel (для процессоров).
В XSLT для указания правила сортировки предусмотрена инструкция
[xsl:sort select=«sort_by_this» /]
Ее можно использовать внутри xsl:apply-templates и xsl:for-each
Вообще есть мнение, что делать сортировки в XSLT — дурной тон, ибо это уже как бы логика, а не представление. Но есть и противоположное мнение. Вообще, у xsl:for-each можно создать чилда:
xsl:sort и там указать настройки сортировки:

<xsl:for-each select="categories/category" >
      <xsl:sort order="ascending" select="@title"/>
      ...


По моему мнение здесь правильней использовать apply-templates вместо for-each (он тяжелый)
заодно можно и задать уровень вложенности, который надо выводить.
не совсем понятно зачем Вы использовали именованый шаблон и for-each, при Вашей структуре данных более красивое решение будет приблизительно такое:
<xsl:template match="/">
<select>
Корневая категория
<xsl:apply-templates select=«categories/category»>
<xsl:with-param name=«space» select="'--'" />
</xsl:apply-templates>
</select>
</xsl:template>

<xsl:template match=«categories/category»>
<xsl:param name=«space»/>
<xsl:value-of select=«concat($space, @title)»/>
<xsl:apply-templates select=«categories/category»>
<xsl:with-param name=«space» select=«concat($space, '--')» />
</xsl:apply-templates>
</xsl:template>

пожалуйста, если ставите минус, напишите почему?
Я не ставлю Вам минус. Ваше решение правильное, хоть и не совсем точное. Мне, в общем-то, и хотелось написать свое решение данной задачи (когда-то у меня на нее ушло много времени) и узнать, какие еще бывают решения.
Плюс за предыдущее сообщение, и минус за это. Не дергайтесь раньше времени, кто-то поставит минус, а кто-то плюс. Сообщение уже в плюсе, а минус ставили видимо за плохое форматирование кода.

Теперь по теме:
Абсолютно верно, такой код гораздо приятнее читать. Я вообще не люблю именованных шаблонов, применяю их лишь для рекурсивной работы со строками, хотя стараюсь перенести эту работу на обычный язык программирования, и давать XSLT уже готовый результат.
Можно сделать более элегантное (но не факт, что более быстрое) решение с отступами, используя глубину вложенности и рекурсивный шаблон:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="html" indent="yes" />
	<xsl:template match="categories">
		<select>
			<xsl:apply-templates select="descendant::category" />
		</select>
	</xsl:template>
	
	<xsl:template match="category">
		<option value="{@id}">
			<xsl:call-template name="pad_string">
				<xsl:with-param name="size" select="count(ancestor::category)"/>
			</xsl:call-template>
			<xsl:value-of select="@title"/>
		</option>
	</xsl:template>
	
	<xsl:template name="pad_string">
		<xsl:param name="space" select="'&#160;&#160;'"/>
		<xsl:param name="size" select="number(0)"/>
		<xsl:if test="$size">
			<xsl:value-of select="$space"/>
			<xsl:call-template name="pad_string">
				<xsl:with-param name="space" select="$space"/>
				<xsl:with-param name="size" select="$size - 1"/>
			</xsl:call-template>
		</xsl:if>
	</xsl:template>	
</xsl:stylesheet>


То есть дополнительно вызываем шаблон pad_string, указывая ему глубину текущего элемента: count(ancestor::category). А шаблон pad_string постоянно вызывает сам себя, снижая количесво отступов.
Оси это, кончено, супер. Но начинающий точно не поймет :)
Если писать весь код так, чтобы понимали начинающие, это будет кошмар.
Темплейт вместо for-each даёт определённые плюшки, например, можно разные ветки красить по-разному:

  <xsl:template match="/">
    <select>
      Корневая категория
      <xsl:apply-templates select="categories/category">
        <xsl:with-param name="space" select = "'--'" />
      </xsl:apply-templates>
    </select>
  </xsl:template>
  <!-- Общий шаблон -->
  <xsl:template match="categories/category">
    <xsl:param name="space"/>
    <option value="{@id}">
      <xsl:value-of select="$space" />
      <xsl:value-of select="@title"/>
    </option>   
    <xsl:value-of select="concat($space, @title)"/>
    <xsl:apply-templates select="categories/category">
      <xsl:with-param name="space" select="concat($space, '--')" />
    </xsl:apply-templates>
  </xsl:template>
  <!-- Персональный шаблон -->
  <xsl:template match="categories/category[@title = 'AMD']">
    <xsl:param name="space"/>
    <option value="{@id}">
      <xsl:value-of select="$space" />
      <xsl:value-of select="@title"/> (sic!)
    </option>
    <xsl:value-of select="concat($space, @title)"/>
    <xsl:apply-templates select="categories/category">
      <xsl:with-param name="space" select="concat($space, '--')" />
    </xsl:apply-templates>
  </xsl:template>
</xsl:stylesheet>


Но в чём профит от осей в данном случае, в чём элегантность-то?
При чем тут for-each? Он в примере вообще не используется. И элегантность примера заключается не в использовании осей, а в более короткой и логичной, на мой взгляд, структуре шаблонов.
Вот для новичков, которым могут быть не понятны оси навигации.
Как могут быть непонятны оси? Как?! Таблица умножения и то сложнее.

Описание понятно с первого раза любому, кто понимает структуру xml документа.
www.w3schools.com/xpath/xpath_axes.asp

А ценность схемы выше стремится к нулю.
Как показывает практика, новички не сразу понимают оси навигации, и лишь по этой схеме им можно объяснить что это такое.
Мне как новичку очень интересны внятные примеры.
С примерами все-таки легче.
Спасибо за статью!
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории