how to select from key which field not empty

i have xml file and xslt transformation below:

    <?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>

How can i select all pets which types not empty using key function?

Answers


Two points to note:

  1. There is an error in your key definition. You need to use use="@type", not use="type"
  2. You need a set difference to select all pets whose type is non-empty, and still use the key() function. The general recipe for set difference in XPATH 1.0 is...

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

Putting it altogether, a correct but inefficent XSLT 1.0 style-sheet to use the key() and list all pets with not empty type is...

<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>

This yields output...

<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>

Having said that, the question does not really fit as a good excersize in using keys. In real life, if you wanted to achieve this outcome, a better, more efficient XSLT 1.0 solution would be ...

<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>

Need Your Help

C++ – Trying to write files

c++ xcode osx file filestream

I'm doing thenewboston tutorials for C++ and have just done a tutorial on file handling. My code looked exactly the same as his but the build failed. I think it might be because I'm on a mac and I ...

Library Not Loaded When Running App on Ipad

ios xcode swift ipad cocoapods

I'm running XCode 6.4 and have an app I'm working on. When I run it on simulator with the iPhone/iPad everything works great. If I simulate it on an iphone 4S everything works fine too. As soon as ...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.