2012-02-16 5 views
1

Я имею шаблонприменить весь шаблон или шаблон части в зависимости от состояния

<xsl:template match="node" mode="some_mode"> 
    <xsl:value-of select="child1" /> 
    <xsl:value-of select="child2" /> 
    <xsl:value-of select="child3" /> 
</xsl:template> 

Я хочу, чтобы применить шаблон таким образом, было бы выбрать все узлы, указанные в шаблоне, в одном случае, как это

<xsl:apply-templates select="node" mode="some_node" /> <!-- select all inside the node tag --> 

и в другом случае я хочу ограничить выход и, например, не выбирать <child1> или <child2> узлов. Могу ли я сделать это с переменной или параметром? Или мне нужно написать еще один шаблон с нуля?

<xsl:apply-templates select="node" mode="some_node" /> <!-- select only some tags from the node tag --> 

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

+0

Этот вопрос действительно расплывчатый. Это очень помогло бы, если бы вы могли предоставить простой пример простого входного документа, вашего ожидаемого результата и объяснения правил в примере преобразования. –

+0

Я обновил пример – tylik

ответ

1

Я боюсь, что это невозможно без изменения шаблона, который у вас есть. Вы можете подумать о сохранении вывода шаблона в переменной, а затем обработать его, чтобы удалить значения child1 и child2. Но я думаю, вы не сможете догадаться, какая часть вашего выхода идет от child1 и/или child2.

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

EDIT: Еще одна идея:

Может быть, можно применить фильтр, чтобы избавиться от child1 и child2 перед применением шаблона (это было бы своего рода многоходовой XSL tranformation).

+0

Вы по-настоящему правы, но это очень грустно, когда у меня есть длинный шаблон, который я использую несколько раз, и jsut хочет ограничить его вывод в некоторых случаях. – tylik

+0

@tylik: см. Мое редактирование ... еще одна идея. – Lukasz

+0

Я думаю, что вы правы, я могу исключить ненужные теги при применении шаблона. Благодаря! – tylik

1

Используйте инструкцию xsl:if внутри вашего шаблона для перехода.

Пример:

<xsl:template match="node"> 
    <xsl:value-of select="child1" /> 
    <xsl:if test="price &gt; 10"> 
     <xsl:value-of select="child2" /> 
     <xsl:value-of select="child3" /> 
    </xsl:if> 
</xsl:template> 

Я надеялся на простом примере в вопросе. Что касается лица, которого нет, я буду составлять простой пример здесь, который отражает ваш вопрос и покажет вам, как инструкция xsl: if является идеальным ответом.

Допустим, у вас есть коллекция музыки, как так ...

<?xml version="1.0"?> 
<catalog> 
    <cd> 
     <title>Empire Burlesque</title> 
     <artist>Bob Dylan</artist> 
     <country>USA</country> 
     <company>Columbia</company> 

     <price>10.90</price> 
     <year>1985</year> 
    </cd> 
    <cd> 
     <title>Hide your heart</title> 
     <artist>Bonnie Tyler</artist> 
     <country>UK</country> 

     <company>CBS Records</company> 
     <price>9.90</price> 
     <year>1988</year> 
    </cd> 

</catalog> 

И вы хотите, чтобы вывести HTML таблицу компакт- листингу названию и цене. Обычно вы хотите как титул, так и цену, но при некоторых условиях (скажем, цена меньше 10 долларов США) вы хотите подавить выход цены и просто иметь статический текст на своем месте, например «дешевле 10,00».

Так что ваш ожидаемый результат должен быть:

<?xml version="1.0" encoding="utf-8"?> 
<table> 
    <tr> 
    <td>Empire Burlesque</td> 
    <td>cheaper than 10.00</td> 
    </tr> 
    <tr> 
    <td>Hide your heart</td> 
    <td>9.90</td> 
    </tr> 
</table> 

Стиль листов для производства этого преобразования может быть:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

     <xsl:template match="/"> 
     <table> 
      <xsl:apply-templates select="//cd"/> 
     </table> 
     </xsl:template> 

     <xsl:template match="cd"> 
     <tr> 
      <td><xsl:value-of select="title"/></td> 
      <xsl:if test="price &lt; 10"> 
      <td><xsl:value-of select="price"/></td> 
      </xsl:if> 
      <xsl:if test="not(price &lt; 10)"> 
      <td>cheaper than 10.00</td> 
      </xsl:if> 
     </tr> 
     </xsl:template> 

</xsl:stylesheet> 

И у вас есть идеальный ответ - как применить весь шаблон или только его части в зависимости от состояния. В этом случае условие заключается в том, что цена составляет менее 10 долларов США.

+0

Я хочу ограничить ouptut в xsl: применить, но не внутри этого шаблона – tylik

+0

Но это ограничивает вывод в приложении! Может, мы говорим не на одном языке? Простой пример нужен. –

+0

Я обновил свой вопрос, извините за мой английский. Я знаю, как использовать xsl: if, но это не так. – tylik

1

Я рекомендую использовать отдельные шаблоны с разными шаблонами соответствия и/или в разных режимах. Это следует отдавать предпочтение использованию условными и, таким образом, писать грязные и потенциально ошибочный код:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:apply-templates mode="allChildren"/> 
========== 
    <xsl:apply-templates mode="child3Only"/> 
</xsl:template> 

<xsl:template match="node" mode="allChildren"> 
    <xsl:copy-of select="*"/> 
</xsl:template> 

<xsl:template match="node" mode="child3Only"> 
    <xsl:copy-of select="child3"/> 
</xsl:template> 
</xsl:stylesheet> 

Когда это преобразование применяется на следующий документ (аналогично тому, который вы использовали в предыдущем вопросе):

<document> 
    <node> 
     <child1>Child 1</child1> 
     <child2>Child 2</child2> 
     <child3>Child 3</child3> 
    </node> 
    <anotherNode /> 
</document> 

разыскиваемый результат получается:

<child1>Child 1</child1><child2>Child 2</child2><child3>Child 3</child3> 

==========

<child3>Child 3</child3> 
+0

Я знаю, что было бы лучше, но подумайте, что этот шаблон имеет длину 200 строк и его нужно использовать 3 раза, каждый раз исключая только пару элементов, поэтому для обработки 3 разных шаблонов потребуется больше времени, чем пытаться исключить что мне не нужно. Я все еще не нашел ответа, хотя было бы здорово написать что-то вроде tylik

+0

@tylik: Ваша большая проблема, что у вас нет при условии какого-либо значимого примера/проблемы. Я подозреваю, что ваша * настоящая * проблема имеет очень простое и эффективное решение. Вам нужно научиться задавать хорошие вопросы. Попробуй еще раз. –

+0

Хм, возможно, вы правы, но вы дали мне ответ на мой вопрос. Мне нужно иметь возможность сортировать некоторые узлы в , чтобы он выбирал все узлы внутри родительского узла, за исключением тех, которые указаны в этом флажке. Если вы заинтересованы в том, чтобы пометить свой ответ как правильный, я сделаю это, если вы можете предоставить правильное выражение xpath – tylik

Смежные вопросы