XSLT Transform doesn't work until I remove root node

I’m trying to extract the headline from the below XML from the Met Office web service using XSLT, however my XSLT select returns blank.


<RegionalFcst xmlns="www.metoffice.gov.uk/xml/metoRegionalFcst" createdOn="2016-01-13T02:14:39" issuedAt="2016-01-13T04:00:00" regionId="se">  <FcstPeriods>   <Period id="day1to2">    <Paragraph title="Headline:">Frosty start. Bright or sunny day.</Paragraph>    <Paragraph title="Today:">A clear and frosty start in west, but cloudier in Kent with isolated showers. Then dry with sunny periods. Increasing cloud in west later will bring coastal showers with freshening southerly winds. Chilly inland, but less cold near coasts. Maximum Temperature 8C.</Paragraph>   </Period>  </FcstPeriods> </RegionalFcst> 


<?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>    <xsl:value-of select="FcstPeriods/Period/Paragraph"/>   </body>   </html> </xsl:template> </xsl:stylesheet> 

I’ve changed the root to /RegionalFcst and attempted other similar changes, such as adding a leading slash before FcstPeriods, but nothing works until I remove the first and last line from the source XML – then it works perfectly.

This is fine in testing, but of course I want to use the web service provided by Met Office and that’s how they present it.

Any ideas?

Add Comment
3 Answer(s)

The problem: your XML puts its elements in a namespace.

Solution: declare the same namespace in your stylesheet, assign it a prefix and use that prefix to address the elements in the source XML:

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:met="www.metoffice.gov.uk/xml/metoRegionalFcst" exclude-result-prefixes="met"> <xsl:template match="/">   <html>   <body>    <xsl:value-of select="met:RegionalFcst/met:FcstPeriods/met:Period/met:Paragraph[@title='Headline:']"/>   </body>   </html> </xsl:template> </xsl:stylesheet> 
Add Comment

Below is the simple change needed in your xsl.

from: <xsl:value-of select="FcstPeriods/Period/Paragraph"/>

to: <xsl:value-of select="//*:FcstPeriods/*:Period/*:Paragraph"/>

Add Comment

There are 2 mistakes in your XSL:

  1. <xsl:value-of select="FcstPeriods/Period/Paragraph"/> will never select anything because <RegionalFcst> and all its child elements are namespaced (xmlns="www.metoffice.gov.uk/xml/metoRegionalFcst").
  2. <xsl:template match="/"> will not match <RegionalFcst> but it will match its parent, the (invisible) document element. <RegionalFcst> is the first and only child of /.

For your XSL to work properly, it would have to look like this:

<?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>                 <xsl:value-of select="*[local-name()='RegionalFcst']/*[local-name()='FcstPeriods']/*[local-name()='Period']/*[local-name()='Paragraph']"/>             </body>         </html>     </xsl:template> </xsl:stylesheet> 
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.