Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with namespace and libxml when i use Xpath

Tags:

xpath

libxml2

i've got a problem when i'm using libxml with XPath. I want to parse an youtube playlist :

<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom'
  xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'
  xmlns:media='http://search.yahoo.com/mrss/'
  xmlns:batch='http://schemas.google.com/gdata/batch'
  xmlns:yt='http://gdata.youtube.com/schemas/2007'
  xmlns:gd='http://schemas.google.com/g/2005'
  gd:etag='W/&quot;Dk8DRn47eCp7ImA9WxRQGEk.&quot;'>
  <id>tag:youtube,2008:user:andyland74:playlists</id>
  <updated>2008-07-21T16:43:25.232Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://gdata.youtube.com/schemas/2007#playlistLink'/>
  <title>Playlists of andyland74</title>
  <logo>http://www.youtube.com/img/pic_youtubelogo_123x63.gif</logo>
  <link rel='related' type='application/atom+xml'
    href='http://gdata.youtube.com/feeds/api/users/andyland74?v=2'/>
  <link rel='alternate' type='text/html'
    href='http://www.youtube.com/profile_play_list?user=andyland74'/>
  <link rel='http://schemas.google.com/g/2005#feed'
    type='application/atom+xml'
    href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists?v=2'/>
  <link rel='http://schemas.google.com/g/2005#post'
    type='application/atom+xml'
    href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists?v=2'/>
  <link rel='http://schemas.google.com/g/2005#batch'
    type='application/atom+xml'
    href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists/batch?v=2'/>
  <link rel='self' type='application/atom+xml'
    href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists?...'/>
  <link rel='service' type='application/atomsvc+xml'
    href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists?alt=...'/>
  <author>
    <name>andyland74</name>
    <uri>http://gdata.youtube.com/feeds/api/users/andyland74</uri>
  </author>
  <generator version='2.0'
    uri='http://gdata.youtube.com/'>YouTube data API</generator>
  <openSearch:totalResults>3</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>25</openSearch:itemsPerPage>
  <entry gd:etag='W/&quot;Dk8DRn47eCp7ImA9WxRQGEk.&quot;'>
    <id>tag:youtube,2008:user:andyland74:playlist:8BCDD04DE8F771B2</id>
    <published>2007-11-04T17:30:27.000-08:00</published>
    <updated>2008-07-15T12:33:20.000-07:00</updated>
    <app:edited xmlns:app='http://www.w3.org/2007/app'>2008-07-15T12:33:20.000-07:00</app:edited>
    <category scheme='http://schemas.google.com/g/2005#kind'
      term='http://gdata.youtube.com/schemas/2007#playlistLink'/>
    <title>My New Playlist Title</title>
    <summary>My new playlist Description</summary>
    <content type='application/atom+xml;type=feed'
      src='http://gdata.youtube.com/feeds/api/playlists/8BCDD04DE8F771B2?v=2'/>
    <link rel='related' type='application/atom+xml'
      href='http://gdata.youtube.com/feeds/api/users/andyland74?v=2'/>
    <link rel='alternate' type='text/html'
      href='http://www.youtube.com/view_play_list?p=8BCDD04DE8F771B2'/>
    <link rel='self' type='application/atom+xml'
      href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists/8BCDD04DE8F771B2?v=2'/>
    <link rel='edit' type='application/atom+xml'
      href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists/8BCDD04DE8F771B2?v=2'/>
    <author>
      <name>andyland74</name>
      <uri>http://gdata.youtube.com/feeds/api/users/andyland74</uri>
    </author>
    <yt:countHint>9</yt:countHint>
  </entry>
</feed>

when i use the following xpath expression "/feed", the xmlXPathEvalExpression say me that i doesnt find.

if i remove all the xmlns attributes of feed it works. How could i make it work even with xmlns attributes ?

i use libxml with objective-C

like image 439
Sly33 Avatar asked Aug 30 '09 14:08

Sly33


4 Answers

I ran into a similar issue when trying to use libxml-ruby to parse through xml. From http://libxml.rubyforge.org/rdoc/classes/LibXML/XML/XPath.html:

To find nodes you must define the atom namespace for libxml. One way to do this is:

node = doc.find('atom:title', 'atom:http://www.w3.org/2005/Atom')

Alternatively, you can register the default namespace like this:

doc.root.namespaces.default_prefix = 'atom' node = doc.find('atom:title')

Either way works, but registering makes sense if you're going to be using the methods a lot. Then you can just reference items like 'atom:title'.

like image 67
alimi Avatar answered Nov 15 '22 19:11

alimi


I am using the XPathQuery wrapper around xmlXPathEvalExpression which makes it harder to go the xmlXpathRegisterNS route.

If you are querying for the fields directly, you probably do not care about the namespaces - it doesn't matter for my app. So, I just modified the XML before I process it.

NSString *xmlString = [[NSString alloc] initWithData:originalXMLData encoding:NSUTF8StringEncoding];
NSString *modifiedXMLString = [xmlString stringByReplacingOccurrencesOfString:@"xmlns=" withString:@"foobar="];
NSData *modifiedXMLData = [modifiedXMLString dataUsingEncoding:NSUTF8StringEncoding];

Now you can use modifiedXMLData in xmlXPathEvalExpression or PerformXMLXPathQuery if you use XPathQuery.

like image 44
Sunil Gowda Avatar answered Nov 15 '22 20:11

Sunil Gowda


You didn't post your query code, but it sounds like you aren't registering the namespaces with your XpathContext. Here's the API docs for xmlXPathRegisterNS, I believe it will do what you're looking for. It won't let you register a default namespace, so you'll need to change your XPath expression to /feed:feed or the like.

like image 2
easel Avatar answered Nov 15 '22 18:11

easel


To use a default namespace just register the namespace xlmns= and then use /xmlns:feed in your query.

like image 2
anton Avatar answered Nov 15 '22 20:11

anton