KDM
KDM

Reputation: 79

XSL transformation fails to find during for-each

I'm trying to create an XSL transformation sheet for an XML set of ISO 19115 codelists, so I can format them nicely for a separate document. However, so far my XSL does not generate anything after it attempts to 'loop' using the first for-each. I have, however, managed to get a similarly structured 'test' document working.

A short version of the XML file I am attempting to parse:

<?xml version="1.0" encoding="UTF-8"?>
<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gml/gml.xsd http://www.w3.org/1999/xlink ../../xlink/xlinks.xsd">
    <codelistItem>
        <CodeListDictionary gml:id="CI_DateTypeCode">
            <gml:description>identification of when a given event occurred</gml:description>
            <gml:identifier codeSpace="ISOTC211/19115">CI_DateTypeCode</gml:identifier>
            <codeEntry>
                <CodeDefinition gml:id="CI_DateTypeCode_creation">
                    <gml:description>date identifies when the resource was brought into existence</gml:description>
                    <gml:identifier codeSpace="ISOTC211/19115">creation</gml:identifier>
                </CodeDefinition>
            </codeEntry>
            <codeEntry>
                <CodeDefinition gml:id="CI_DateTypeCode_publication">
                    <gml:description>date identifies when the resource was issued</gml:description>
                    <gml:identifier codeSpace="ISOTC211/19115">publication</gml:identifier>
                </CodeDefinition>
            </codeEntry>
            <codeEntry>
                <CodeDefinition gml:id="CI_DateTypeCode_revision">
                    <gml:description>date identifies when the resource was examined or re-examined and improved or amended</gml:description>
                    <gml:identifier codeSpace="ISOTC211/19115">revision</gml:identifier>
                </CodeDefinition>
            </codeEntry>
        </CodeListDictionary>
    </codelistItem>
</CT_CodelistCatalogue>

The XSL I am working with is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gml/gml.xsd http://www.w3.org/1999/xlink ../../xlink/xlinks.xsd">
    <xsl:output method="html"/>
    <xsl:template match="/">
        <html>
            <head>
                <title>Codelists</title>
            </head>
            <body>
            The first table should be below this.
            <xsl:for-each select="CT_CodelistCatalogue/codelistItem/CodeListDictionary">
                We have found an item and are creating a list of elements. NB: It never gets to this line
                <table>
                    <xsl:for-each select="codeEntry/CodeDefinition">
                        <tr>
                          <td><xsl:value-of select="gml:identifier"/></td>
                          <td><xsl:value-of select="gml:description"/></td>
                        </tr>
                    </xsl:for-each>
                </table>
            </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet> 

This XSL generates the following HTML output. Note that there isn't even a "table" call, so it is as if the for-each is failing to find a matching element.

<html xmlns="http://www.isotc211.org/2005/gmx"
      xmlns:gco="http://www.isotc211.org/2005/gco"
      xmlns:gml="http://www.opengis.net/gml/3.2"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <head>
      <title>Codelists</title>
   </head>
   <body>
            The first table should be below this.
            </body>
</html>

To try to solve my problem, I was messing around in w3schools' demo environment and made a similarly structured XML - just with different element names and no attributes.

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <title>My catalog</title>
  <disc>
  <cd>
    <title>Empire Burlesque</title>
    <firstname>blank</firstname>
    <lastname>dude</lastname>
    <performer>
      <artist>
        <firstname>Bob</firstname>
        <lastname>Dylan</lastname>
      </artist>
    </performer>
    <performer>
      <artist>
        <firstname>Job</firstname>
        <lastname>Bylan</lastname>
      </artist>
    </performer>
  </cd>
  </disc>
  <disc>
  <cd>
    <title>Hide your heart</title>
    <firstname>test</firstname>
    <lastname>case</lastname>
    <performer>
      <artist>
        <firstname>Bonnie</firstname>
        <lastname>Tyler</lastname>
      </artist>
    </performer>
  </cd>
  </disc>
</catalog>

and XSL, which correctly generates output.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h2>My CD Collection</h2>
    <xsl:for-each select="catalog/disc/cd">
        <h3><xsl:value-of select="title" /></h3>
    <table border="1">
      <xsl:for-each select="performer/artist">
      <tr>
        <td><xsl:value-of select="firstname" /></td>
        <td><xsl:value-of select="lastname" /></td>
      </tr>
      </xsl:for-each>
    </table>
    </xsl:for-each>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

The above XML and XSL generate my expected tabular output.

<body>
  <h2>My CD Collection</h2>
  <h3>Empire Burlesque</h3>
  <table border="1">
    <tbody>
      <tr>
        <td>Bob</td><td>Dylan</td>
      </tr>
      <tr>
        <td>Job</td><td>Bylan</td>
      </tr>
    </tbody>
  </table>
  <h3>Hide your heart</h3>
  <table border="1">
    <tbody>
      <tr>
        <td>Bonnie</td><td>Tyler</td>
      </tr>
    </tbody>
  </table>
</body>

I'm really hoping this is some simple mistake I'm making, but I've been stuck for a while and probably could use some external advice.

Thanks!

Upvotes: 0

Views: 33

Answers (1)

Stefan Hegny
Stefan Hegny

Reputation: 2177

The difference is easy - the original xml has a default namespace declaration xmlns="http://www.isotc211.org/2005/gmx" and so your loop wont find anything unless you also use that namespace.

Use it e.g. as xmlns:gmx="http://www.isotc211.org/2005/gmx" at the root of the xsl and then use it like <xsl:for-each select="gmx:CT_CodelistCat...

Upvotes: 1

Related Questions