XSLT复制文本节点

时间:2014-01-10 19:29:33

标签: xml xslt

我正在试图弄清楚如何将样式元素应用于不同的结构元素。

我的XML看起来像这样:

 <?xml version="1.0" encoding="ISO-8859-1"?>
    <catalog>
        <cd>
            <title>Empire Burlesque</title>
            <artist><bold>Bob</bold> Dylan</artist>
        </cd>
        <cd>
            <title>Hide your <bold>heart</bold></title>
            <artist>Bonnie Tyler</artist>
        </cd>
    </catalog>

我最新的XSLT尝试看起来像这样

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

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

<xsl:template match="/catalog">
  <html>
  <body>
    <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Artist</th>
      </tr>
      <xsl:for-each select="cd">
      <tr>
        <td><xsl:value-of select="title" /><xsl:apply-templates/></td>
        <td><xsl:value-of select="artist" /><xsl:apply-templates/></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>


</xsl:stylesheet>

但结果会复制数据,而不是只是以粗体显示所需的部分。

3 个答案:

答案 0 :(得分:1)

以下是您的需求:

      <xsl:for-each select="cd">
        <tr>
          <td><xsl:apply-templates select="title"/></td>
          <td><xsl:apply-templates select="artist"/></td>
        </tr>
      </xsl:for-each>

由于您没有匹配titleartist的任何模板,因此默认设置是将文本节点复制到输出中。你不需要自己这样做。

这是一个使用更多惯用“推”处理的修改:

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

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

  <xsl:template match="/catalog">
    <html>
      <body>
        <h2>My CD Collection</h2>
        <table border="1">
          <tr bgcolor="#9acd32">
            <th>Title</th>
            <th>Artist</th>
          </tr>
          <xsl:apply-templates select="cd"/>
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="cd">
    <tr>
      <td><xsl:apply-templates select="title"/></td>
      <td><xsl:apply-templates select="artist"/></td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

这是使用较少显式元素匹配的另一个选项。在许多情况下,这将是您想要的,因为它更简单,更灵活。在某些情况下,不会成为您想要的,因为您需要单独处理每个元素。 YMMV。

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/catalog">
        <html>
            <body>
                <h2>My CD Collection</h2>
                <table border="1">
                    <tr bgcolor="#9acd32">
                        <th>Title</th>
                        <th>Artist</th>
                    </tr>
                    <xsl:apply-templates />
                </table>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="cd">
        <tr><xsl:apply-templates /></tr>
    </xsl:template>
    <xsl:template match="cd/*">
        <td><xsl:apply-templates /></td>
    </xsl:template>
    <xsl:template match="bold">
        <b><xsl:apply-templates /></b>
    </xsl:template>
</xsl:stylesheet>

答案 2 :(得分:0)

您使用xsl:value-of处理一次,然后再使用xsl:apply-templates;如果您不希望它被处理两次,那么只需将其中一个切掉。

相关问题