使用XSL删除重复项

时间:2013-02-22 13:41:24

标签: xslt

这是当前的XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<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>Empire Burlesque</title>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>
    <cd>
        <title>Still got the blues</title>
        <artist>Gary Moore</artist>
        <country>UK</country>
        <company>Virgin records</company>
        <price>10.20</price>
        <year>1990</year>
    </cd>
</catalog>

当前XSL:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <html>
      <body>
        <table border="1">
          <xsl:variable name="a" select="count(catalog/cd[contains(title,'Empire Burlesque')])"/>
          <xsl:for-each select="catalog/cd">
            <tr>
              <td>
                <xsl:choose>
                  <xsl:when test="$a = '2' and contains(title,'Empire Burlesque') ">
                    <xsl:text>pass</xsl:text>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="title"/>
                  </xsl:otherwise>
                </xsl:choose>
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

出于此:

pass
Hide your heart
pass
Still got the blues

预期产出:

Empire Burlesque
Hide your heart
pass
Still got the blues

我不希望重复'Empire Burlesque'而应该在第二次用'pass'替换它。 有人可以帮助我,我一定出错了吗?

2 个答案:

答案 0 :(得分:0)

这是一个选项:

样式表

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"/>

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

  <xsl:template match="catalog">
    <table border="1">
      <xsl:apply-templates select="cd"/>
    </table>
  </xsl:template>

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

  <xsl:template match="title">
    <td>
      <xsl:value-of select="."/>
    </td>
  </xsl:template>

  <!--
  Match <title> elements that contain the string "Empire Burlesque" with a
  preceding element like it. This template will be applied rather than the
  one above because it has a higher specificity (as in, it is more specific
  about what kind of node it's looking for).
  -->
  <xsl:template match="title[contains(., 'Empire Burlesque') and
                       preceding::title[contains(., 'Empire Burlesque')]]">
    <td>pass</td>
  </xsl:template>
</xsl:stylesheet>

输入

<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>Empire Burlesque</title>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>
    <cd>
        <title>Still got the blues</title>
        <artist>Gary Moore</artist>
        <country>UK</country>
        <company>Virgin records</company>
        <price>10.20</price>
        <year>1990</year>
    </cd>
</catalog>

输出

<html>
  <body>
    <table border="1">
      <tr>
        <td>Empire Burlesque</td>
      </tr>
      <tr>
        <td>Hide your heart</td>
      </tr>
      <tr>
        <td>pass</td>
      </tr>
      <tr>
        <td>Still got the blues</td>
      </tr>
    </table>
  </body>
</html>

另外,如果可以的话,您需要avoid <xsl:for-each>并使用<xsl:apply-templates>代替,将代码拆分为整齐,可读的块。

答案 1 :(得分:0)

如果在XSLT 1中进行分组或重复删除,那么您希望使用密钥来查找“Muenchian分组”技术:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:key name="t" match="title" use="."/>

  <xsl:template match="/">
    <html>
      <body>
        <table border="1">
          <xsl:for-each select="catalog/cd">
            <tr>
              <td>
                <xsl:choose>
                  <xsl:when test="generate-id(title)=generate-id(key('t',title))[1]">
                    <xsl:value-of select="title"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:text>pass</xsl:text>
                  </xsl:otherwise>
                </xsl:choose>
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

可生产

<html>
   <body>
      <table border="1">
         <tr>
            <td>Empire Burlesque</td>
         </tr>
         <tr>
            <td>Hide your heart</td>
         </tr>
         <tr>
            <td>pass</td>
         </tr>
         <tr>
            <td>Still got the blues</td>
         </tr>
      </table>
   </body>
</html>