通过使用xslt检查,删除了输出xml中没有值的输入xml中的标签

时间:2018-09-10 10:21:57

标签: xml xslt

我是xslt的新手。试图从结果/输出xml中删除标签,该标签没有输入xml中存在的标签值。但是输出xml,要打印的标签会多次出现。

输入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></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>
  </catalog>

XSLT

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" 
indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  <html>
  <body>
    <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Artist</th>
<th>Price</th>
      </tr>
      <xsl:for-each select="catalog/cd">
      <tr>
        <td><xsl:value-of select="title" /></td>
        <td><xsl:value-of select="artist" /></td>
<td><xsl:value-of select="price" /></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
<xsl:template match="price[not(node())]"/>
</xsl:stylesheet>

预期输出的HTML

没有<price></price>标签的打印没有价值,但实际上显示为输出的是所有标签的多个值 请帮助我

<html>
   <body>
      <h2>My CD Collection</h2>
      <table border="1">
         <tr bgcolor="#9acd32">
            <th>Title</th>
            <th>Artist</th>
            <th>Price</th>
         </tr>
         <tr>
            <td>Empire Burlesque</td>
            <td>Bob Dylan</td>

         </tr>
         <tr>
            <td>Hide your heart</td>
            <td>Bonnie Tyler</td>
            <td>9.90</td>
         </tr>
      </table>
   </body>
</html>            

但是我得到的是它多次循环打印。

2 个答案:

答案 0 :(得分:0)

add a condition for price tag
<xsl:template match="/">

        <html>
            <body>
                <h2>My CD Collection</h2>
                <table border="1">
                    <tr bgcolor="#9acd32">
                        <th>Title</th>
                        <th>Artist</th>
                        <th>Price</th>
                    </tr>
                    <xsl:for-each select="catalog/cd">
                        <tr>
                            <td><xsl:value-of select="title" /></td>
                            <td><xsl:value-of select="artist" /></td>
                            <xsl:choose>
                                <xsl:when test="price = ''"/>
                                <xsl:otherwise><td><xsl:value-of select="price" /></td></xsl:otherwise>
                            </xsl:choose>

                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>

答案 1 :(得分:0)

脚本的问题是您将所有内容放在模板中 匹配@*|node()

具有这种匹配的模板通常是 identity template ,用于创建XML输出。

但是脚本的输出是HTML标记,具有转换后的输入 内部(每个cd元素)。

我的建议是:

  • match="@*|node()"更改为match="/"(您的模板应匹配 仅文档节点)。
  • 将片段从<xsl:copy>删除到</xsl:copy>(包括)。

编辑

另一个问题是,如果要获取HTML输出, 输出方法可能应该是html而不是xml

下面有重新编写的脚本,生成XHTML:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" doctype-public="-//W3C//DTD XHTML 1.1//EN"
    doctype-system= "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>

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

如果需要,请根据需要更改两个doctype-...属性。

请注意,price不需要空模板,因为:

  • 匹配/的模板可以完成所有工作,而无需调用apply-templates
  • 因此,price元素不可能被处理为匹配项 通过任何模板。