Conditional test around xsl:apply-templates

左心房为你撑大大i 提交于 2020-01-24 11:30:05

问题


I've been trying to learn how to code in xslt and currently am stuck on how to use conditional tests around the xsl:apply-templates tag.

Here's the xml that I am testing.

<?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>

Here is my 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>

Here is my output:

Bob Dylan
USA

Bonnie Tyler
UK
1988

Dolly Parton
USA

Here is the output I was expecting:

Bob Dylan
USA

Bonnie Tyler
UK
1988

Dolly Parton
USA
1982

Even though I want to remove the year only when country has a value of USA and year has a value of 1985 it is removing the year every time country has a value of USA only. Is there a better way I can use apply-templates?


回答1:


You might prefer to apply templates to the wanted node set directly, without conditional "if" check.

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



回答2:


Simply correct your logic.

Replace:

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

with:

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

and even better, apply templates only on the wanted nodes:

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

Do note:

As demonstrated, it is possible to specify the Xpath expression in the select attribute without using any reverse axes (going back and forth).




回答3:


This helped me, thank you. I was expanding upon this very example and trying to call one template for a certain attribute (I had edited the XML to eg <artist sex="male">Bob Dylan</artist> My attempts were failing but i worked it out. This code allowed me to create conditional templates in >1 scenario: -

<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>

Hope this helps and is useful to someone! The output produced the artist name in a different colour depending on their sex.




回答4:


You want to remove the year if the country is USA and if the year is 1985.

Therefore, you want to copy the year if the country is not USA or if the year is not 1985.

Your condition should use an or instead of an and. Note that not(a and b) = (not a) or (not b).



来源:https://stackoverflow.com/questions/11023458/conditional-test-around-xslapply-templates

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!