XPath with namespace

XPath の処理系には javax.xml.xpath.* と org.apache.xpath.* とがある(他にもあるけれど).
これらを同時に import しちゃうと,動くものも動かない.
パスを切るのが面倒なので,当面,javax.xml.xpath.* を使うことにした.

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;
import org.w3c.dom.traversal.*;

import javax.xml.xpath.*;
import javax.xml.parsers.*;
import javax.xml.namespace.NamespaceContext;


DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(url);
	    
XPathFactory f = XPathFactory.newInstance();
XPath xpath = f.newXPath();
	    
xpath.setNamespaceContext(new HatenaNamespaceContext());

//例その1
String xpathstring = "//default:channel/default:title";
String result = xpath.evaluate(xpathstring, doc);
System.out.println("result : " + result);

//例その2
xpathstring = "//default:item";
NodeList entries = (NodeList) xpath.evaluate(xpathstring, doc, XPathConstants.NODESET);
for(int i = 0; i < entries.getLength(); i++){
  String link = (String)xpath.evaluate("default:link", entries.item(i), XPathConstants.STRING);
  String title = (String)xpath.evaluate("default:title", entries.item(i));
  String description = (String)xpath.evaluate("default:description", entries.item(i));
  String date = (String)xpath.evaluate("dc:date", entries.item(i));
  System.out.println(link + "\n" + date);
}

HatenaNamespaceContext.java

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

public class HatenaNamespaceContext implements NamespaceContext
{
    public String getNamespaceURI(String prefix)
    {
	if (prefix.equals("default"))
	    return "http://purl.org/rss/1.0/";
	else if (prefix.equals("rdf"))
	    return "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
	else if (prefix.equals("dc"))
	    return "http://purl.org/dc/elements/1.1/";
	else if (prefix.equals("opensearch"))
	    return "http://a9.com/-/spec/opensearchrss/1.0/";
	else
	    return XMLConstants.NULL_NS_URI;
    }
    
    // dummy (not used)
    public String getPrefix(String namespace)
    {
	System.out.println("namespace : " + namespace);
	if (namespace.equals("http://www.w3.org/1999/02/22-rdf-syntax-ns#"))
	    return "rdf";
	else if (namespace.equals("http://apache.org/bar"))
	    return "bar";
	else
	    return null;
    }
    
    // dummy (not used)
    public Iterator getPrefixes(String namespace)
    {
	System.out.println("getPrefixes() called");
	return null;
    }
}