1

I'm having trouble extracting XML nodes using Xpath in Java. Here is the URL for the YouTube feed I am using

http://gdata.youtube.com/feeds/api/videos?q=skateboarding+dog&start-index=21&max-results=10&v=2

Here's an extract of the feed

<?xml version="1.0" encoding="UTF-8" ?> 
- <feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:media="http://search.yahoo.com/mrss/" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:yt="http://gdata.youtube.com/schemas/2007" gd:etag="W/"CEANQ3o9fCp7I2A9WhBbFEg."">
  <id>tag:youtube.com,2008:videos</id> 
  <updated>2013-05-13T13:46:32.464Z</updated> 
  <category scheme="http://schemas.google.com/g/2005#kind" term="http://gdata.youtube.com/schemas/2007#video" /> 
  <title>Videos matching: skateboarding dog</title> 
  <logo>http://www.youtube.com/img/pic_youtubelogo_123x63.gif</logo> 
  <link rel="alternate" type="text/html" href="http://www.youtube.com" /> 
  <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/videos?v=2" /> 
  <link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/videos/batch?v=2" /> 
  <link rel="self" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/videos?q=skateboarding+dog&start-index=21&max-results=10&v=2" /> 
  <link rel="service" type="application/atomsvc+xml" href="http://gdata.youtube.com/feeds/api/videos?alt=atom-service&v=2" /> 
  <link rel="previous" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/videos?q=skateboarding+dog&start-index=11&max-results=10&v=2" /> 
  <link rel="next" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/videos?q=skateboarding+dog&start-index=31&max-results=10&v=2" /> 
+ <author>
  <name>YouTube</name> 
  <uri>http://www.youtube.com/</uri> 
  </author>
  <generator version="2.1" uri="http://gdata.youtube.com">YouTube data API</generator> 
  <openSearch:totalResults>277515</openSearch:totalResults> 

I have created a NamespaceContext class

import java.util.Iterator;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;

public class YouTubeNameSpaceContext implements NamespaceContext {

@Override
public String getNamespaceURI(String prefix) {
    if (prefix == null) throw new NullPointerException("Invalid Namespace Prefix");
    else if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX))
        return "http://www.w3.org/2005/Atom";
    else if ("app".equals(prefix))
        return "http://www.w3.org/2007/app";
    else if ("media".equals(prefix)) 
        return "http://search.yahoo.com/mrss/";
    else if ("openSearch".equals(prefix)) 
        return "http://a9.com/-/spec/opensearch/1.1/";
    else if ("gd".equals(prefix))
        return "http://schemas.google.com/g/2005";      
    else if ("yt".equals(prefix)) 
        return "http://gdata.youtube.com/schemas/2007";
    else    
        return XMLConstants.NULL_NS_URI;
}

@Override
public String getPrefix(String arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public Iterator getPrefixes(String arg0) {
    // TODO Auto-generated method stub
    return null;
}

}

The Java which I'm using to get the XML node. THe node I'm trying to get is but the result is always 'null' :(

XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext(new YouTubeNameSpaceContext());

String QUERY_FORM_NUMBER =  "//feed/openSearch:totalResults"; 

Node result = (Node)xPath.evaluate(QUERY_FORM_NUMBER, document, XPathConstants.NODE);
Hevski
  • 1,821
  • 1
  • 17
  • 26
  • Why do you think you only need to implement `getNamespaceURI()` and not `getPrefix()`? – parsifal May 13 '13 at 14:38
  • Also: what namespace does `feed` belong to, and why aren't you referencing that in your XPath? – parsifal May 13 '13 at 14:39
  • Hmmm I only implemented `getNamespaceURI()` and not `GetPrefix()` because I was following this example http://stackoverflow.com/questions/5465840/xpath-xml-namespaces-and-java, but I don't 100% understand it. The `feed` node is the root node it doesn't belong to any namespace, does it? (XML isn't my speciality so I don't really know..). Do I need to implement getPrefix? – Hevski May 13 '13 at 14:47
  • Regarding which methods you need to implement: I'm sure that it depends on implementation. It's best to implement both (typically using something like a [BidiMap](http://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections/BidiMap.html)). – parsifal May 13 '13 at 14:57
  • As for the `feed` namespace, yes, it has one: ` – parsifal May 13 '13 at 14:57
  • The feed node is specifies the default namespace xmlns="http://www.w3.org/2005/Atom", I'm not sure what it is I have to change to get this to work. In my `namespacecontent` class I have the code '(prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) return "http://www.w3.org/2005/Atom";' is this what you mean? – Hevski May 13 '13 at 15:12
  • XPath 1.0 (which is what the JDK supports) does not know about default namespaces; you must create a prefix for every namespace (see [this](http://www.w3.org/TR/1999/REC-xpath-19991116/#node-tests), and compare to [XPath 2.0](http://www.w3.org/TR/xpath20/#node-tests)). – parsifal May 13 '13 at 15:21
  • Could you provide the code example in an answer as to how I might achieve this? – Hevski May 13 '13 at 18:10

0 Answers0