views:

136

answers:

1

I have the following XML and I am trying to get a reference to the media:thumbnail and media:content URL attributes using the value-of statement in the XSL. I am able to get the title, link, description, etc, but not the media nodes and their attributes (url, width, height for thumbnail and url, medium, type, width, and height for group).

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/"&gt;
<channel>
   <item>
      <title>My Title</title>
      <link>http://MyLink.com&lt;/link&gt;
      <description>My description</description>
      <pubDate>Wed, 18 Aug 2010 18:31:24 UTC</pubDate>
      <media:thumbnail url="MyLink.com/Thumbnail.gif" width="80" height="80" />
      <media:group>
         <media:content url="http://MyLink.com/image1.gif" medium="image" type="image/jpeg" width="80" height="80"  />
         <media:content url="http://MyLink.com/image2.gif" medium="image" type="image/jpeg" width="30" height="30"  />
      </media:group>
   </item>
</channel>
</rss>

Here is my XSL...

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:media="http://search.yahoo.com/mrss/"&gt;

 <xsl:template match="rss">

 <xsl:for-each select="channel/item/*">
    <xsl:value-of select="name()"/><br />

 <!-- What goes here to display Media:Thumbnail @URL and Media:Content @URL ? -->

 </xsl:for-each>

 </xsl:template>
</xsl:stylesheet>

The example XSL prints out the following for each item node but displays nothing for the media nodes.

title<br />
link<br />
description<br />
pubDate<br />
+1  A: 

I tried your code samples with Xmlstarlet and it printed all element names, even the ones with media: prefix, so probably either you or me is using buggy software. Anyway, here is a workaround.

You can use a node test that is in form namespace-prefix:* to select all elements in a certain namespace and a pipe character | to get an union of the selection paths. So in this case for-each line

<xsl:for-each select="channel/item/* | channel/item/media:*">

should do what you wanted. Note that the prefix doesn't have to be the same that is used in the XML document but it has to match the prefix defined in your XSLT document.

If the problem would be the opposite, one could use the selection
channel/item/*[not(self::media:*)] to rule out an unwanted namespace or use selection
<xsl:for-each select="channel/item/*[namespace-uri(.)='']"> to select only elements with no namespace definition.

jasso