如何从键中选择哪个字段不为空

时间:2012-09-09 06:55:07

标签: xml xslt xslt-1.0 xslkey

我在下面有xml文件和xslt转换:

    <?xml version="1.0" encoding="utf-8" ?>
    <?xml-stylesheet version="1.0" type="text/xml" href="pets.xsl" ?>
    <pets>
        <pet name="Jace" type="dog" />
        <pet name="Babson" type="" />
        <pet name="Oakley" type="cat" />
        <pet name="Tabby" type="dog" />
    </pets>

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:key name="pets-key" match="pet" use="type" />
    <xsl:template match="/" >
        <html>
            <head><title></title></head>
            <body>
                <xsl:for-each select="key('pets-key', '' )" >
                    <xsl:value-of select="@name" />
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

如何使用按键功能选择所有非空类型的宠物?

1 个答案:

答案 0 :(得分:1)

需要注意的两点:

  1. 您的密钥定义中存在错误。你需要使用use =“@ type”,而不是使用=“type”
  2. 您需要一组设置差异来选择所有类型为非空的宠物,并且仍然使用key()函数。 XPATH 1.0中设置差异的一般方法是......

    $ node-set1 [count(。| $ node-set2)!= count($ node-set2)]

  3. 总而言之,一个正确但无效的XSLT 1.0样式表使用key()并列出所有非空类型的宠物是...

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="html" indent="yes" />
    <xsl:strip-space elements="*" />
    
    <xsl:key name="kPets" match="pet" use="@type" />
    
    <xsl:template match="/" >
      <html>
        <head><title>Pets with a type</title></head>
        <body>   
          <ul>
            <xsl:for-each select="*/pet[count(. | key('kPets', '' )) != count(key('kPets', '' ))]" >
              <li><xsl:value-of select="@name" /></li>
            </xsl:for-each>
          </ul>
        </body>
       </html>
    </xsl:template>
    
    </xsl:stylesheet>
    

    这会产生输出......

    <html>
      <head>
        <META http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Pets with a type</title>
      </head>
      <body>
        <ul>
          <li>Jace</li>
          <li>Oakley</li>
          <li>Tabby</li>
        </ul>
      </body>
    </html>
    

    话虽如此,这个问题在使用密钥方面并不适合作为一个好的例外。在现实生活中,如果您想实现这一目标,那么更好,更高效的XSLT 1.0解决方案将是......

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="html" indent="yes" />
    <xsl:strip-space elements="*" />
    
    <xsl:key name="kPets" match="pet" use="@type" />
    
    <xsl:template match="/*" >
      <html>
        <head><title>Pets with a type</title></head>
        <body>   
          <ul>
            <xsl:apply-templates />
          </ul>
        </body>
       </html>
    </xsl:template>
    
    <xsl:template match="pet[@type != .]">
      <li><xsl:value-of select="@name" /></li>
    </xsl:template>  
    
    </xsl:stylesheet>