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; } }