Gareth
Gareth

Reputation: 35

Transform XML using XSL

I'm formatting an xml file with a simple XSL which works fine when there is no additional data in the container tag but doesnt display any data if there is data in the tag.

When the XML is like this it's fine

<Result>
 <primaryTopic> 
  <CompanyName>ZENITH PRINT (UK) LIMITED</CompanyName>
  <RegAddress>
    <AddressLine1>ZENITH HOUSE</AddressLine1>
    <AddressLine2>MOY ROAD INDUSTRIAL ESTATE</AddressLine2>
    <PostTown>TAFFS WELL</PostTown>
    <County>CARDIFF</County>
    <Postcode>CF15 7QR</Postcode>
  </RegAddress>

When there is url data in the tag like this it fails

<Result xmlns="http://#####.uk/terms/xxx">
 <primaryTopic> 
  <CompanyName>ZENITH PRINT (UK) LIMITED</CompanyName>
  <RegAddress href="http://#####.uk/doc/company/02050399#RegAddress">
    <AddressLine1>ZENITH HOUSE</AddressLine1>
    <AddressLine2>MOY ROAD INDUSTRIAL ESTATE</AddressLine2>
    <PostTown>TAFFS WELL</PostTown>
    <County>CARDIFF</County>
    <Postcode>CF15 7QR</Postcode>
  </RegAddress>

The XSL I'm using

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h2><xsl:value-of select="Result/primaryTopic/CompanyName"/></h2>
    <table border="1">
      <tr>
        <td>Company Name</td>
        <td><xsl:value-of select="Result/primaryTopic/CompanyName"/></td>
        <td>Address</td>
        <td><xsl:value-of select="Result/primaryTopic/RegAddress/AddressLine1"/></td>
      </tr>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

Upvotes: 0

Views: 293

Answers (2)

Tim C
Tim C

Reputation: 70648

The problem is that for the second sample, a default namespace has been specified, and so all the elements in the XML will be part of that namespace

<Result xmlns="http://#####.uk/terms/xxx">

However, your XSLT is looking for elements which have no namespace, and so it won't match the elements in the XML, which do have a namespace.

The solution is to make sure the namespace is part of your XSLT when you match the elements

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xxx="http://#####.uk/terms/xxx" exclude-result-prefixes="xxx">
   <xsl:template match="/">
      <html>
         <body>
            <h2>
               <xsl:value-of select="xxx:Result/xxx:primaryTopic/xxx:CompanyName"/>
            </h2>
            <table border="1">
               <tr>
                  <td>Company Name</td>
                  <td>
                     <xsl:value-of select="xxx:Result/xxx:primaryTopic/xxx:CompanyName"/>
                  </td>
                  <td>Address</td>
                  <td>
                     <xsl:value-of select="xxx:Result/xxx:primaryTopic/xxx:RegAddress/xxx:AddressLine1"/>
                  </td>
               </tr>
            </table>
         </body>
      </html>
   </xsl:template>
</xsl:stylesheet>

Of course, this will only work on your second XML sample, not the first. If you want an XSLT that will work with both samples, you could do something like this to check for element names regardless of namespace.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/*/*[local-name()='primaryTopic']">
      <html>
         <body>
            <h2>
               <xsl:value-of select="*[local-name() = 'CompanyName']"/>
            </h2>
            <table border="1">
               <tr>
                  <td>Company Name</td>
                  <td>
                     <xsl:value-of select="*[local-name() = 'CompanyName']"/>
                  </td>
                  <td>Address</td>
                  <td>
                     <xsl:value-of select="*[local-name() = 'RegAddress']/*[local-name() = 'AddressLine1']"/>
                  </td>
               </tr>
            </table>
         </body>
      </html>
   </xsl:template>
</xsl:stylesheet>

This should give the same output for both the first and second XML samples.

Upvotes: 1

Udy_athium
Udy_athium

Reputation: 3

Your XSL works fine for both XMLs. There must be something else going wrong. Adding a attribute to a XML node must not effect the transformation.

Upvotes: 0

Related Questions