Search

I have a problem with the xpath expression for an external XML source, and I have no clue why. I tested the example given at the sneakpeak site and that works perfectly. Now, when I try to import my Picasa feed I am not able to specify some xml elements to import, the only thing that works is using / as including element.

Find the feed at http://picasaweb.google.com/data/feed/base/user/fleshy.nl/albumid/5158685807312920113?kind=photo

The xml structure of the picasa feed is as follows:

<feed>
    <entry></entry>
    <entry></entry>
</feed>

So, one would expect that I could put in the above URL as external XML source and then use feed/entry as included elements. However, when I try this I get an No Records Found.. Even "feed" as included elements does not work. Any ideas why?

Have you declared your namespaces?

I have, using the data source editor. If I do not define any namespace it will still work using "/" as "included elements".

hmm. I'll look into it.

Okay, it looks like the XML you are grabbing is an Atom feed. Atom feeds have a quirk in them that is slightly annoying. If you have a look at the namespace declaration on the feed element:

<feed xmlns="http://www.w3.org/2005/Atom"
     xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"
     xmlns:exif="http://schemas.google.com/photos/exif/2007"
     xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
     xmlns:gml="http://www.opengis.net/gml" xmlns:georss="http://www.georss.org/georss"
     xmlns:photo="http://www.pheed.com/pheed/" xmlns:media="http://search.yahoo.com/mrss/"
     xmlns:batch="http://schemas.google.com/gdata/batch"
     xmlns:gphoto="http://schemas.google.com/photos/2007">

Of particular concern is xmlns="http://www.w3.org/2005/Atom". If you want to read more about the quirks of default namepsaces, head over to: http://symphony21.com/forum/discussions/1122/1/.

The solution is simple:

On your namespace declaration, put atom as your name and http://www.w3.org/2005/Atom as your URI.

Then on your Included Elements input, put atom:feed. That will grab the feed element. You can traverse the XPath further to grab more specific elements you want, but I'll leave that to you.

I'm unable to get a Del.icio.us feed working. I'm not sure I understand how the new external XML datasource works. I am able to add my feed and get the XML, but I get the XSLT error mentioned above.

I've tried adding all the namespaces in the datasource and set the default one to rss and included elements to rss:item, but I always get 'no records found' in the XML. I must have my Xpath wrong?

Here are the namespaces in the feed:

<?xml version="1.0" encoding="UTF-8"?>

<rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns="http://purl.org/rss/1.0/"
 xmlns:content="http://purl.org/rss/1.0/modules/content/"
 xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
 xmlns:admin="http://webns.net/mvcb/"
 >

Attached is the whole feed.

Thanks!

Attachments

Also, when I do give my default namespace a name, in this case rss, in the data source when the XML is written it still outputs a default namespace of BLANK -- as in nothing.

In my data source I have this:

Namespace Name rss

URI http://purl.org/rss/1.0/

Included Elements /rdf:RDF/rss:item

The XML looks like this for each <item> node:

&lt;mrblank-delicious status="fresh" creation="2008-02-07T00:43:17-06:00"&gt;
&lt;item xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" rdf:about="http://www.hometracked.com/2008/02/05/auto-tune-abuse-in-pop-music-10-examples/"&gt;
 &lt;title&gt;Auto-Tune Abuse in Pop Music - 10 Examples&lt;/title&gt;
 &lt;link&gt;http://www.hometracked.com/2008/02/05/auto-tune-abuse-in-pop-music-10-examples/&lt;/link&gt;
---- the rest of the XML here ---

So what's the problem exactly?

The reason why the namespace on the resultant XML still has the "blank" namespace is because that is what was declared in the XML source.

There are two sets of namespaces you have to consider. One on the XML and the other on the XSLT. By redefining the default namespace in the XSLT, that is for the benefit of your XPath.

Also, as a side note, it is not necessary to define all the namespaces from the XML. The only ones required are ones you use on your XPath.

The problem I'm having is that even though I've defined the default namespace to be rss instead of nothing, I still get the error:

XSLTProcessor::transformToXml(): Undefined namespace prefix

I'm thinking I have a problem with my datasource and the Included Elements Xpath. I've set the Xpath to /, /rss:item, /rdf:RDF or /rdf:RDF/rss:item but I get the XSLT error either way.

Where do the defined namespaces appear in the XSLT? I just see the ones the Datasource pulls from the feed, which include the default one that I'm trying to change. Do I need to manually add the namespaces to the XSLT? I tried to do that, but I got the same error.

Would it be possible to have access to your copy or is it local?

Do I need to manually add the namespaces to the XSLT? I tried to do that, but I got the same error.

You don't have to. The data source should declare the namespaces on the relevant nodes for you.

OK, I found my problem.

In the Datasource:

  • I declared the default namespace name as rss with the URI of http://purl.org/rss/1.0/

  • I set my Included Elements to rdf:RDF/rss:item[position()&lt;=15]

Then anytime I call a node from the feed that has the default namespace, I add rss: in front of it.

Example:

Instead of <xsl:template match="mrblank-delicious/item">

I do this <xsl:template match="mrblank-delicious/rss:item">

Then I added the newly defined namespace to my xslt and use the exclude-result-prefixes attribute so the namspaces don't show up in the output.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rss="http://purl.org/rss/1.0/" version="1.0" exclude-result-prefixes="rss">

Thanks, Allen for all the help in getting me to understand this. :-)

Default namespaces are a pest. It's quirky and sometimes hard to wrap your head around. Thankfully, the only popular XML format that uses default namespace is RDF RSS.

On this topic, has anyone managed to actually get the Yahoo! Weather namespace to work for them? I've been trying to extract some data from the Yahoo! Weather RSS feed for a while now, but the data I want is held in the < yweather:condition > element. It took me a while to figure out that I was supposed to add a namespace declaration to the data source, so I added one called "yweather" with a URI of http://weather.yahooapis.com/ns/rss/1.0 .

However, still, when I try to get the attribute "text" from element "yweather:condition", I get the undefined namespace error. I'm a bit lost. Any help anywhere?

Oh... I'm using the following to get to the element:

< xsl:value-of select="rss/channel/item/yweather:condition/@text" />

Where am I going wrong?

Cheers

David

Can you post the source XML here? If the document is too long, then use something like http://pastie.org/ and provide the link here.

I had to declare the namespaces I was using in my XSLT stylesheet tag as well. Here is part of my Del.icio.us feed XSLT:

<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:rss="http://purl.org/rss/1.0/" version="1.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  exclude-result-prefixes="rss dc">

--the rest of the stylesheet--

</xsl:stylesheet>

The exclude-result-prefixes="rss dc" keeps the namespaces from being declared in my XHTML.

I imagine you would have something like this:

<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:yweather="http://weather.yahooapis.com/ns/rss/1.0"
  exclude-result-prefixes="yweather">

--the rest of the stylesheet--

</xsl:stylesheet>

Okay, so I have put the namespace in the stylesheet, shich stops the error being thrown, but now I just cant get to the information... My stylesheet is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rss="http://purl.org/rss/1.0/" version="1.0"
xmlns:yweather="http://weather.yahooapis.com/ns/rss/1.0"
exclude-result-prefixes="yweather">

<xsl:template match="weather">

<xsl:param name="stuff" select="yweather:condition/@text" />

<xsl:choose>
<xsl:when test="string-length($stuff) = 0">

  <p>no data found</p>

</xsl:when>

<xsl:otherwise>
  <p><xsl:value-of select="$stuff" /></p>
</xsl:otherwise>
</xsl:choose>

</xsl:template>

</xsl:stylesheet>

And the xml feed is like this:

<weather status="fresh" creation="2008-02-22T10:50:30+00:00">
<rss xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
  <channel>

  <title>Yahoo! Weather - Birmingham, UK</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Birmingham__UK/*http://weather.yahoo.com/forecast/UKXX0018_f.html</link>
  <description>Yahoo! Weather for Birmingham, UK</description>
  <language>en-us</language>
  <lastBuildDate>Fri, 22 Feb 2008 9:50 am GMT</lastBuildDate>
  <ttl>60</ttl>
  <yweather:location city="Birmingham" region="" country="UK"/>
  <yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/>
  <yweather:wind chill="52" direction="220" speed="22"/>
  <yweather:atmosphere humidity="82" visibility="6.21" pressure="30.03" rising="0"/>
  <yweather:astronomy sunrise="7:11 am" sunset="5:33 pm"/>
  <image>
    <title>Yahoo! Weather</title>
    <width>142</width>
    <height>18</height>
    <link>http://weather.yahoo.com</link>
    <url>http://l.yimg.com/us.yimg.com/i/us/nws/th/main_142b.gif</url>
  </image>
  <item>
    <title>Conditions for Birmingham, UK at 9:50 am GMT</title>
    <geo:lat>52.43</geo:lat>
    <geo:long>-1.95</geo:long>
    <link>http://us.rd.yahoo.com/dailynews/rss/weather/Birmingham__UK/*http://weather.yahoo.com/forecast/UKXX0018_f.html</link>
    <pubDate>Fri, 22 Feb 2008 9:50 am GMT</pubDate>
    <yweather:condition text="Mostly Cloudy" code="28" temp="52" date="Fri, 22 Feb 2008 9:50 am GMT"/>
    <description>
      &lt;img src="http://l.yimg.com/us.yimg.com/i/us/we/52/28.gif"/&gt;&lt;br /&gt;
      &lt;b&gt;Current Conditions:&lt;/b&gt;&lt;br /&gt;
      Mostly Cloudy, 52 F&lt;BR /&gt;
      &lt;BR /&gt;&lt;b&gt;Forecast:&lt;/b&gt;&lt;BR /&gt;
      Fri - Rain. High: 54 Low: 44&lt;br /&gt;
      Sat - Light Rain. High: 54 Low: 44&lt;br /&gt;
      Sun - AM Fog/PM Clouds. High: 53 Low: 42&lt;br /&gt;
      Mon - AM Light Rain. High: 49 Low: 42&lt;br /&gt;
      Tue - Light Rain. High: 50 Low: 41&lt;br /&gt;
      &lt;br /&gt;
      &lt;a href="http://us.rd.yahoo.com/dailynews/rss/weather/Birmingham__UK/*http://weather.yahoo.com/forecast/UKXX0018_f.html"&gt;Full Forecast at Yahoo! Weather&lt;/a&gt;&lt;BR/&gt;
      (provided by The Weather Channel)&lt;br/&gt;
    </description>
    <yweather:forecast day="Fri" date="22 Feb 2008" low="44" high="54" text="Rain" code="12"/>
    <yweather:forecast day="Sat" date="23 Feb 2008" low="44" high="54" text="Light Rain" code="11"/>
    <yweather:forecast day="Sun" date="24 Feb 2008" low="42" high="53" text="AM Fog/PM Clouds" code="20"/>
    <yweather:forecast day="Mon" date="25 Feb 2008" low="42" high="49" text="AM Light Rain" code="11"/>
    <yweather:forecast day="Tue" date="26 Feb 2008" low="41" high="50" text="Light Rain" code="11"/>
    <guid isPermaLink="false">UKXX0018_2008_02_22_9_50_GMT</guid>
  </item>
  </channel>
  </rss><!-- api2.weather.re4.yahoo.com uncompressed Fri Feb 22 02:34:17 PST 2008 -->
  </weather>

In the stylesheet, I have set it so that if the param "$stuff" returns empty, it outputs "no data found". I'm always getting that... which means that the param is never actually getting the info that I want. for the select, i've tried a number of variations on "rss/channel/item/yweather:condition/@text", "yweather:condition/@text", "yweather:item/condition/@text"... nothing seems to work. I'm at a loss.

Help? :-)

Do the following:

  1. Change the yweather namespace declaration on your XSLT to xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
  2. Remove the rss namespace declaration on your XSLT, it's not necessary
  3. Change your parameter's XPath to: rss/channel/item/yweather:condition/@text

Below is the fixed XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
    version="1.0"
    exclude-result-prefixes="yweather">

<xsl:template match="weather">
    <xsl:param name="stuff" select="rss/channel/item/yweather:condition/@text" />

    <xsl:choose>
        <xsl:when test="string-length($stuff) = 0">
            <p>no data found</p>
        </xsl:when>

        <xsl:otherwise>
            <p><xsl:value-of select="$stuff" /></p>
        </xsl:otherwise>
    </xsl:choose>

</xsl:template>

</xsl:stylesheet>

Thanks for the help there, guys! I'll hopefully be using this to drive something pretty clever on the site I'm working on... I'll be sure to let you all know when its done!

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details