Kody
Kody

Reputation: 762

PHP Parse XML with colon in tag name using children

I have the following php code:

$xml=simplexml_load_file("http://openclipart.org/api/search/?query=dog&page=1");
echo "<ul>";
foreach ($xml->channel->item as $clipinfo):
  $title=$clipinfo->title;
  $full=$clipinfo->enclosure['url'];
  $thumb=$clipartinfo->children('media', true)->thumbnail['url'];

  echo "<div style=\"width:160px;height:120px;float:left;margin:5px;margin-top:10px;\">    
  <a href=\"{$full}\" target='_blank' class=\"thumbnail\">
  <img alt=\"{$title}\" style=\"width: 160px; height: 120px;\" src=\"{$thumb}\">
  </a>
  </div>";
endforeach;

This is being fed by the following XML file:

<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>OpenClipart.org</title>
    <atom:link rel="self" href="http://openclipart.org/api/search/?query=dog&amp;page=1" type="application/rss+xml"/>
    <link>http://openclipart.org</link>
    <description>Download, Sample, Cut-up, Share.</description>
    <language>en-US</language>
    <image>
    <url>http://openclipart.org/assets/images/images/logo-no-text.jpg</url>
    <link>http://openclipart.org</link>
    <title>OpenClipart.org</title>
    <height>93</height>
    <width>114</width>
    </image>
    <item>
      <title>walking dog</title>
      <link>http://openclipart.org/detail/720/walking-dog-by-johnny_automatic</link>
      <pubDate>Tue, 17 Oct 2006 21:23:37 -0400</pubDate>
      <dc:creator>johnny_automatic</dc:creator>
      <description>cartoon of a girl walking a dog from  http://www.usda.gov/cnpp/KidsPyra/National Agricultural Library, Agricultural Research Service, U. S. Department of Agriculture</description>
      <enclosure url="http://openclipart.org/people/johnny_automatic/johnny_automatic_walking_dog.svg" type="image/svg+xml" length="99841"/>
      <guid>http://openclipart.org/detail/720/walking-dog-by-johnny_automatic</guid>
      <cc:license>http://creativecommons.org/licenses/publicdomain</cc:license>
      <media:thumbnail url="http://openclipart.org/image/90px/svg_to_png/720/johnny_automatic_walking_dog.png"/>
    </item>

Why can't I get the <media:thumbnail> url attribute with my foreach statement? (I have already read PHP library for parsing XML with a colons in tag names?) This is a different issue.

Upvotes: 2

Views: 4999

Answers (2)

Amal Murali
Amal Murali

Reputation: 76636

First of all, you're using an undefined variable in your foreach loop. You've defined $clipinfo but you're trying to use $clipartinfo in your code.

Second, you're accessing the attributes incorrectly:

<media:thumbnail url="http://openclipart.org/image/foo.png"/>

You're trying to access the URL attribute. This needs to be done with attributes() method.

Change:

$thumb=$clipartinfo->children('media', true)->thumbnail['url'];

to:

$thumb = $clipinfo->children('media', true)->thumbnail->attributes()->url;

Hope this helps!

Upvotes: 12

IMSoP
IMSoP

Reputation: 97938

Attributes are not automatically in the same namespace as the element they appear on. If the XML contained <media:thumbnail media:url="...." />, then the attribute would be in the namespace currently assigned the prefix media, the same namespace as the thumbnail element, and your code would work fine.

However, a quirk of the XML namespace specification is that "The namespace name for an unprefixed attribute name always has no value." - that is, an attribute without a namespace prefix is explicitly not in any namespace, regardless of what else is defined in the document. (See also XML Namespaces and Unprefixed Attributes)

In SimpleXML, this means if you've switched to a specific namespace with ->children, you have to explicitly switch back to the "null" namespace to access the attribute, using the ->attributes() method. This should work:

 $thumb = $clipinfo->children('media', true)->thumbnail->attributes(null)->url;

Upvotes: 1

Related Questions