2012-06-13 1 views
3

Я пытался узнать, как кодировать в xslt и в настоящее время зацикливается на том, как использовать условные тесты вокруг тега xsl: apply-templates.Условный тест вокруг xsl: apply-templates

Вот xml, который я тестирую.

<?xml version="1.0" encoding="utf-8"?> 
<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> 
<cd> 
    <title>Greatest Hits</title> 
    <artist>Dolly Parton</artist> 
    <country>USA</country> 
    <company>RCA</company> 
    <price>9.90</price> 
    <year>1982</year> 
</cd> 

Вот мой XSLT

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

<xsl:template match="cd"> 
    <p> 
    <xsl:apply-templates select="artist" /> 
    <br /> 
    <xsl:apply-templates select="country" /> 
    <br /> 
    <xsl:if test="country != 'USA' and year != '1985'"> 
     <xsl:apply-templates select="year" /> 
    </xsl:if> 
    </p> 
</xsl:template> 

<xsl:template match="artist"> 
    <xsl:value-of select="." /> 
</xsl:template> 

<xsl:template match="country"> 
    <xsl:value-of select="." /> 
</xsl:template> 

<xsl:template match="year"> 
    <xsl:value-of select="." /> 
</xsl:template> 

Вот мой результат:

Bob Dylan 
USA 

Bonnie Tyler 
UK 
1988 

Dolly Parton 
USA 

Здесь выход я ожидал:

Bob Dylan 
USA 

Bonnie Tyler 
UK 
1988 

Dolly Parton 
USA 
1982 

Несмотря на то, что я хочу удалить год только тогда, когда страна имеет значение США, а год имеет значение 1985 года, он удаляет год каждый раз, когда страна имеет ценность только для США. Есть ли лучший способ использовать шаблоны-заявки?

ответ

3

Возможно, вы захотите применить шаблоны к нужному узлу напрямую, без условной проверки «если».

<xsl:apply-templates select="year[not(../country='USA' and ../year='1985)]" /> 
+2

Спасибо! Я не пробовал использовать функцию not. Также спасибо за информацию о логике. До сих пор кажется, что многие мои ошибки связаны с условиями. – Mdd

-1

Вы хотите удалить год, если страна США и если год 1985.

Таким образом, вы хотите скопировать год, если страна не США или если год не 1985.

Ваше состояние должно использовать or вместо and. Обратите внимание, что not(a and b) = (not a) or (not b).

+1

Логика говорит нам, что 'not (A и B) = не A или не B'. Это известно в логике как законы ДеМоргана. –

+0

Большое спасибо. Я довольно хорошо знаком с тегом call-template и for-each, но при чтении о xslt кажется, что многие люди предпочитают шаблоны-шаблоны, поэтому я работаю, чтобы понять, что лучше. Еще раз спасибо. – Mdd

+0

@empo: Спасибо, что указали недостающую «не» формулу ... Я должен был оставить решение так, как было до того, как я добавил третью строку ;-) –

1

Просто исправить вашу логику.

Заменить:

<xsl:if test="country != 'USA' and year != '1985'"> 

с:

<xsl:if test="country != 'USA' or year != '1985'"> 

и даже лучше, применять шаблоны только на пожелавших узлов:

<xsl:apply-templates select= 
    "self::*[country != 'USA' or year != '1985']/year"/> 

Обратите внимание:

Как было показано, что можно указать выражение Xpath в атрибуте select без использования каких-либо обратных осей (вперед и назад).

1

Это помогло мне, спасибо. Я расширил этот пример и попытался вызвать один шаблон для определенного атрибута (я отредактировал XML, например, <artist sex="male">Bob Dylan</artist> Мои попытки потерпели неудачу, но я решил это сделать.Этот код позволил мне создать условные шаблоны в сценарии> 1: -

<xsl:template match="cd"> 
    <p> 
     <xsl:apply-templates select="title"/> 
     <xsl:apply-templates select="artist [@sex = 'male']"/> 
     <xsl:apply-templates select="artist [@sex = 'female']"/> 
     <xsl:apply-templates select="year"/> 
    </p> 
</xsl:template> 

<xsl:template match="title"> 
    Title: <span style="color:#ff0000"> 
     <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

<xsl:template match="artist [@sex = 'male']"> 
    Artist: <span style="color:#e9d419"> 
     <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

<xsl:template match="artist [@sex = 'female']"> 
    Artist: <span style="color:#48b8ff"> 
     <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

<xsl:template match="year"> 
    Year: <span style="color:#eb47dc"> 
     <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

Надеюсь, что это помогает и полезно кому-то! Результат произвел имя художника в другом цвете в зависимости от их пола.