Xslt xsl使用条件测试应用模板

Xslt xsl使用条件测试应用模板,xslt,xslt-1.0,Xslt,Xslt 1.0,我一直在尝试将测试添加到xsl:apply templates元素中,但我不断收到一个错误,即“表达式的计算结果不适用于节点集”。我想知道是否有人能指出我做错了什么,为我指明正确的方向 这是我的XML <?xml version="1.0" encoding="utf-8"?> <catalog> <cd> <title>Empire Burlesque</title> <artist>Bob Dylan&l

我一直在尝试将测试添加到xsl:apply templates元素中,但我不断收到一个错误,即“表达式的计算结果不适用于节点集”。我想知道是否有人能指出我做错了什么,为我指明正确的方向

这是我的XML

<?xml version="1.0" encoding="utf-8"?>
<catalog>
<cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
        <band>
            <guitar>Joe</guitar>
            <drums>Rachel</drums>
            <bass>Mike</bass>
        </band>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
</cd>
<cd>
    <title>Hide your heart</title>
    <artist>Bonnie Tyler</artist>
        <band>
            <guitar>Cat</guitar>
            <drums>Paul</drums>
            <bass>Bobby</bass>
        </band>     
    <country>UK</country>
    <company>CBS Records</company>
    <price>9.90</price>
    <year>1988</year>
</cd>
<cd>
    <title>Greatest Hits</title>
    <artist>Dolly Parton</artist>
        <band>
            <guitar>Eric</guitar>
            <drums>Bill</drums>
            <bass>Jason</bass>
        </band>     
    <country>USA</country>
    <company>RCA</company>
    <price>9.90</price>
    <year>1982</year>
</cd>
</catalog>
以模板为例

<xsl:template match="cd">
  <p style="color:red;">
    <xsl:apply-templates select="title = 'Empire Burlesque'" />
  </p>
  <p style="color:blue;">
    <xsl:apply-templates select="artist = 'Bob Dylan'" />
  </p>
  <p style="color:green;">
    <xsl:apply-templates select="band/guitar = 'Joe'" />
  </p>
</xsl:template>

这说明了语法问题和逻辑问题

语法优先:给定一个cd元素作为当前节点,表达式“title”计算为一个节点集。表达式“title=‘Empire Bullesque’”的计算结果为布尔值。如果要将模板应用于每个具有字符串值“Empire Bullesque”的标题子级,则需要编写类似于“title[.='Empire Bullesque']”的内容。修复所有三个select表达式后,将获得预期的输出

现在,逻辑

此模板将针对输入中的每个cd元素计算一次。因此,一旦修复了select表达式,您将获得预期的输出,然后是

<p style="color:red;"/>
<p style="color:blue;"/>
<p style="color:green;"/>
<p style="color:red;"/>
<p style="color:blue;"/>
<p style="color:green;"/>

前三个空段落将由邦妮·泰勒CD生成,后三个由多莉·帕顿生成


如果您认为HTML是一种只写的语言,这可能不会造成任何特别的伤害,但它在您的输出中是一种不必要的丑陋。将您的条件放在正确的位置。

条件按以下方式建立:

<xsl:template match="cd">
  <p style="color:red;">
    <xsl:apply-templates select="title[text()='Empire Burlesque']" />
  </p>
  <p style="color:blue;">
    <xsl:apply-templates select="artist[text()='Bob Dylan']" />
  </p>
  <p style="color:green;">
    <xsl:apply-templates select="band/guitar[text()='Joe']" />
  </p>
</xsl:template>


谢谢!我通过添加更新了方法。这是可行的,但是在最后的标记之后,所有剩余的XML节点值都会打印到页面上。我是否错过了另一个条件测试?我将更新添加到原始问题中。再次感谢您花时间解释我在第一次尝试中遇到的缺陷。我看看是否更改为,并在以下ti工程上应用条件测试:)很高兴看到您找到了解决方案。发生的情况是:如果您将当前cd模板上的匹配模式更改为match=“cd[title=‘Empire Bullesque’”,则其他cd元素将由默认模板匹配,该模板在其子项上调用apply templates;这又意味着其他cd元素的子元素的文本节点由文本节点的默认模板处理,该模板将打印出它们的字符串值。感谢您的解释。我在谷歌上搜索了xslt默认模板,现在看到了,但我真的明白了为什么会显示这么多,谢谢。使用
[.='Joe']
比使用
[text()='Joe']
更好(因此,向下投票)。要了解原因,请查看XML包含注释时会发生什么:
Empire-bullesque
。现在有两个文本节点,都不等于“Empire Bullesque”,但对字符串值的测试仍然有效。
<p style="color:red;"/>
<p style="color:blue;"/>
<p style="color:green;"/>
<p style="color:red;"/>
<p style="color:blue;"/>
<p style="color:green;"/>
<xsl:template match="cd">
  <p style="color:red;">
    <xsl:apply-templates select="title[text()='Empire Burlesque']" />
  </p>
  <p style="color:blue;">
    <xsl:apply-templates select="artist[text()='Bob Dylan']" />
  </p>
  <p style="color:green;">
    <xsl:apply-templates select="band/guitar[text()='Joe']" />
  </p>
</xsl:template>