XSLT шпаргалка: apply-templates

Сегодня мы поговорим о конструкции <xsl:apply-templates />. Данная конструкция очень активно используется при формировании таких xslt шаблонов, как:

  • обработка группы полей (вывод характеристик товара),
  • формирования форм,
  • создание шаблонов для разных типов страниц и тому подобное.

Данная конструкция позволяет обработать часть текущего xml и вывести его, используя отдельный шаблон. Чем-то она похожа на <xsl:value-of />, но если первый выводит конкретное значение, то текущая конструкция позволяет обработать  кусок xml и вывести результат по отдельному шаблону.

Как обычно, посмотрим, что нам говорит о данной конструкции интернет:

Элемент <xsl:apply-templates /> - Предписывает XSLT-процессору найти и применить соответствующий шаблон в зависимости от типа и контекста каждого выбранного узла.

(взято с msdn.microsoft.com)

У данной конструкции есть следующие атрибуты:

  • select - указывает, что именно вы хотите вывести. Тут можно поставить xPath выражение, которое сформирует выборку из несколько узлов или атрибутов, укажет на часть текущего xml , переменной или параметра. Eсли этот атрибут не задан, выбираются все дочерние элементы текущего узла.
  • mode - атрибут, позволяющий дополнительно связать точку вызова (<xsl:apply-templates />) и шаблон, который будет обрабатывать результаты данной конструкции (<xsl:template />)

 Давайте рассмотрим некоторые примеры:

Возьмем маленький xml , который можно получить, обратившись к любой странице в UMI.CMS, добавив .xml в конце её значения в адресной строке (например http://example.ru/test.xml)

<result module="content" method="content" domain="example.ru" system-build="49344" lang="ru" header="Тестовая страница" title="UMI.CMS - Тестовая страница" site-name="test site" request-uri="/test/.xml" pageId="7">
	<meta>
		<keywords>umihelp.ru UMI.CMS umi тестовый сайт</keywords>
		<description/>
	</meta>
	<user id="2" status="auth" login="admin" xlink:href="uobject://2" type="sv"/>
	<parents/>
	<page id="7" parentId="0" link="/test/" is-active="1" object-id="351" type-id="60" type-guid="content-page" update-time="1425309789" alt-name="test">
		<basetype id="30" module="content">Страницы контента</basetype>
		<name>Тестовая страница</name>
		<properties>
			<group id="84" name="common">
				<title>Общее</title>
				<property id="3" name="h1" type="string">
					<title>Поле H1</title>
					<value>Тестовая страница</value>
				</property>
				<property id="4" name="content" type="wysiwyg">
					<title>Контент</title>
					<value>
						<p>Вы находитесь на тестовой странице созданной для umihelp.ru проекта</p>
					</value>
				</property>
			</group>
			<group id="86" name="more_params">
				<title>Дополнительные параметры</title>
				<property id="12" name="show_submenu" type="boolean">
					<title>Показывать подменю</title>
					<value>1</value>
				</property>
				<property id="416" name="info_page" type="boolean">
					<title>Информационная страница</title>
					<value>1</value>
				</property>
			</group>
		</properties>
	</page>
</result>


xml страницы http://example.ru/test/

 

  1. Обработка всех узлов property и вывод их по шаблону следующего вида “Название поля: значение поля”.

    Такая задача, может встать перед вами при выводе всех характеристик товара.
    <xsl:template match="...">
    	...
    	
    	<xsl:apply-templates select="//property" />
    	...
    </xsl:template>
    
    <xsl:template match="property">
    	<strong>
    		<xsl:value-of select="title" />
    	</strong>: 
    	<xsl:value-of select="value" />
    </xsl:template>

    Тут нужно дать несколько пояснений:
    - Описание конструкции <xsl:template /> будет дано позже, сейчас просто договоримся, что это блок с шаблоном. Чтобы система понимала для чего предназначен этот шаблон, у данной конструкции есть атрибут match, где прописываем название узла, который мы обрабатываем в данном случае.
    - Во многих примерах кодов встречается знак "..." (многоточие), который я использую для упрощения записи самого примера. Но следует понимать, что в реальной практике вместо “” (многоточия) будут прописаны какие-то элементы, текст или конструкции.
  2. Использование атрибута mode.
    Обработки всех узлов property и вывода их по двум разным шаблонам. Первый, уже знакомый нам “Название поля: значение поля”. Второй, произвольного вида, отличного от первого. Например такой: “Только название поля”.

    Подобная задача может встать перед вами, когда вы хотите обработать xml меню в двух местах (шапке и футере сайта), оформив их по разному.
    <xsl:template match="...">
    	...
    	<xsl:apply-templates select="//property" />
    	<xsl:apply-templates select="//property" mode="second_type"/>
    	...
    </xsl:template>
    
    <xsl:template match="property">
    	<strong>
    		<xsl:value-of select="title" />
    	</strong>: 
    	<xsl:value-of select="value" />
    	<br/>
    </xsl:template>
    
    <xsl:template match="property" mode="second_type">
    	<xsl:value-of select="title" /><br/>
    </xsl:template>
  3. Вложенные вызовы.
    Рассмотрим пример, когда мы делаем несколько вложенных вызовов . Например, мы хотим вывести блок с названием группы полей и внутри этого блока вывести все поля данной группы.
    <xsl:template match="...">
    	...
    	
    	<xsl:apply-templates select="//group" />
    	...
    </xsl:template>
    
    
    <xsl:template match="group">
    	<div>
    		<h3>
    			<xsl:value-of select="title" />
    		</h3>
    		
    		<xsl:apply-templates select=".//property" />
    	</div>
    </xsl:template>
    
    
    <xsl:template match="property">
    	<strong>
    		<xsl:value-of select="title" />
    	</strong>: 
    	<xsl:value-of select="value" />
    	<br/>
    </xsl:template>
  4. Уточняющие шаблоны.
    Это одна из самых мощных методик при разработке xslt. Когда вы хотите обработать какой-то элемент (например, узел property), вы можете создать сколь угодно точные инструкции о том, что и как выводить.

    Например, вы хотите вывести все поля типа "Строка" обычным шаблоном, а поля типа “Кнопка-галочка” в виде строчки “Да” , если данная галочка установлена. Для этого, вам достаточно прописать уточняющий шаблон для соответствующего типа поля.
    <xsl:template match="...">
    	...
    	<xsl:apply-templates select="//property" />
    	...
    </xsl:template>
    
    
    <xsl:template match="property">
    	<strong>
    		<xsl:value-of select="title" />
    	</strong>: 
    	<xsl:value-of select="value" />
    	<br/>
    </xsl:template>
    
    
    <xsl:template match="property[@type = 'boolean']">
    	<strong>
    		<xsl:value-of select="title" />
    	</strong>: Да <br/>
    </xsl:template>
    И таких уточняющих шаблонов может быть сколь угодно много. Вы можете создать общий шаблон, затем шаблон для определенных типов полей, затем добавить шаблоны к конкретным полям (например, проверяя их имя через xml атрибут @name) и т.д.

P.S. Безусловно, в нашей короткой шпаргалке не раскрыть всех граней применения конструкции <xsl:apply-templates />, поэтому не забывайте пробовать свои задумки и практиковать её использование.



comments powered by HyperComments