xsl:apply-templates如何正常工作?为什么它会写2次名称?

时间:2013-08-31 11:27:36

标签: xml xslt apply-templates

我正在使用http://www.freeformatter.com/xsl-transformer.html。这是我的XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="listacd_es1.xslt"?>

<listacd>
    <artista>
        <nome>Stanley Jordan</nome>
        <albums>
            <album>
                <titolo>Magic Touch</titolo>
                <anno>1985</anno>
                <etichetta>Blue Note</etichetta>
            </album>
            <album>
                <titolo>Stolen Moments</titolo>
                <anno>1991</anno>
                <etichetta>Blue Note</etichetta>
            </album>
        </albums>
    </artista>
    <artista>
        <nome>Nick Drake</nome>
        <albums>
            <album>
                <titolo>Pink Moon</titolo>
                <anno>1972</anno>
                <etichetta>Island</etichetta>
            </album>
            <album>
                <titolo>Bryter Layter</titolo>
                <anno>1970</anno>
                <etichetta>Island</etichetta>
            </album>
            <album>
                <titolo>Five leaves left</titolo>
                <anno>1970</anno>
                <etichetta>Island</etichetta>
            </album>
        </albums>
    </artista>
    <artista>
        <nome>Jeff Buckley</nome>
        <albums>
            <album>
                <titolo>Grace</titolo>
                <anno>1994</anno>
                <etichetta>Columbia</etichetta>
            </album>
            <album>
                <titolo>Mistery white boy</titolo>
                <anno>2000</anno>
                <etichetta>Columbia</etichetta>
            </album>
        </albums>
    </artista>
    <artista>
        <nome>Joe Satriani</nome>
        <albums>
            <album>
                <titolo>Surfing with the alien</titolo>
                <anno>1987</anno>
                <etichetta>Epic</etichetta>
            </album>
            <album>
                <titolo>Not of this earth</titolo>
                <anno>1988</anno>
                <etichetta>Relativity</etichetta>
            </album>
        </albums>
    </artista>
</listacd>

这是XSLT文件:

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

    <xsl:template match="/">
        <html>
            <xsl:apply-templates />
        </html>
    </xsl:template>

    <xsl:template match="artista">
        <b>
            <xsl:value-of select="nome" /> :
        </b>
        <xsl:apply-templates />
        <br />
        <br />
    </xsl:template>

    <xsl:template match="album">
        <xsl:value-of select="titolo" />
    </xsl:template>

</xsl:stylesheet>

结果如下:

<?xml version="1.0" encoding="UTF-8"?>
<html>
  <b>Stanley Jordan :</b>
  Stanley JordanMagic TouchStolen Moments
  <br />
  <br />
  <b>Nick Drake :</b>
  Nick DrakePink MoonBryter LayterFive leaves left
  <br />
  <br />
  <b>Jeff Buckley :</b>
  Jeff BuckleyGraceMistery white boy
  <br />
  <br />
  <b>Joe Satriani :</b>
  Joe SatrianiSurfing with the alienNot of this earth
  <br />
  <br />
</html>

我知道结果不是很漂亮,我不在乎,但我不明白为什么艺术家的名字被写了2次。我该怎么办才能让名字每个艺术家只出现一次?

1 个答案:

答案 0 :(得分:2)

这与XSLT的built-in templates部分相关。这些是在找不到与样式表中的节点匹配的特定模板时使用的模板。内置模板将输出任何文本节点匹配的文本,否则它将简单地跳过节点并继续处理其子节点。

由于此模板而出现问题

<xsl:template match="artista">
    <b>
        <xsl:value-of select="nome" /> :
    </b>
    <xsl:apply-templates />
    <br />
    <br />
</xsl:template>

特别是<xsl:apply-templates />行。这将查找与当前 artista 元素的子节点匹配的模板,在您的情况下, nome 相册,两者都没有在XSLT中匹配模板。因此,内置模板适用,对于 nome 元素,将输出其中的文本,这是复制文本的来源。

有两种可能的简单解决方案。首先,您可以将此模板添加到XSLT中以匹配XSLT中的 nome ,并忽略它,以防止内置模板应用:

 <xsl:template match="nome" />

第二种解决方案是从 artista 模板中删除当前<xsl:value-of select="." />,而是使用与 nome 匹配的模板,在那里输出值。试试这个XSLT作为这个

的一个例子
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <xsl:apply-templates />
        </html>
    </xsl:template>

    <xsl:template match="artista">
        <xsl:apply-templates />
        <br />
        <br />
    </xsl:template>

    <xsl:template match="album">
        <xsl:value-of select="titolo" />
    </xsl:template>

    <xsl:template match="nome">
        <b>
            <xsl:value-of select="." /> :
        </b>
   </xsl:template>
</xsl:stylesheet>