开发者

Select Attribute of XML Node within a Namespace with XSL

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/">
<channel>
   <item>
      <title>My Title</title>
      <link>http://MyLink.com</link>
      <description>My description</description>
      <pubDate>Wed开发者_JS百科, 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/">

 <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 />


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜