我有xml如下(Google API),但无法获得gphoto:id
元素值。怎么做 ?注意:当我使用domFactory.setNamespaceAware(true);
时,/feed/entry
xpath停止工作。
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:gphoto="http://schemas.google.com/photos/2007"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
<entry>
<title type="text">Test</title>
<author>
<name>username</name>
<uri>https://picasaweb.google.com/113422203255202384532</uri>
</author>
<gphoto:id>57060151229174417</gphoto:id>
</entry>
</feed>
爪哇
NodeList nodes = (NodeList) path(body, "/feed/entry", XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
Node n = nodes.item(i);
XPath xpath = XPathFactory.newInstance().newXPath();
// empty :(
System.out.println(
xpath.evaluate("id[namespace-uri()='http://schemas.google.com/photos/2007']",n)
);
// empty too :(
System.out.println(
xpath.evaluate("gphoto:id",n)
);
// ok
System.out.println(
xpath.evaluate("author",n)
);
l.add(new Album("", "", ""));
}
路径方法
private Object path(String content, String path, QName returnType) {
try {
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(content)));
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile(path);
return expr.evaluate(doc, returnType);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
已解决根据@gioele回答path()
方法现在如下所示:
private Object path(String content, String path, QName returnType) {
try {
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(content)));
XPath xpath = XPathFactory.newInstance().newXPath();
NamespaceContext nsContext = new NamespaceContext() {
@Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
@Override
public String getPrefix(String namespaceURI) {
return null;
}
@Override
public String getNamespaceURI(String prefix) {
if ("gphoto".equals(prefix))
return "http://schemas.google.com/photos/2007";
if ("media".equals(prefix))
return "http://search.yahoo.com/mrss/";
if("".equals(prefix))
return "http://www.w3.org/2005/Atom";
throw new IllegalArgumentException(prefix);
}
};
xpath.setNamespaceContext(nsContext);
XPathExpression expr = xpath.compile(path);
return expr.evaluate(doc, returnType);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
答案 0 :(得分:3)
在编译xpath之前,您需要注册NamespaceContext
。
如果您想避免所有这些并发症,可以使用XPathAPI library:
Map<String, String> nsMap = new HashMap<String, String>();
nsMap.put(XMLConstants.DEFAULT_NS_PREFIX, "http://www.w3.org/2005/Atom");
nsMap.put("gphoto", "http://schemas.google.com/photos/2007");
List<Node> entries = XPathAPI.selectListOfNodes(doc, "/feed/entry", nsMap);
for (Node entry : entries) {
String id = XPathAPI.selectSingleNodeAsString(entry, "gphoto:id", nsMap);
// or, if you prefer a Node
// Node id = XPathAPI.selectSingleNode(entry, "gphoto:id", nsMap);
}
免责声明:我是XPathAPI-JAXP的创建者。
答案 1 :(得分:3)
处理命名空间问题的一种更简单的方法是将调用从NamespaceContext重定向到文档lookupNamespaceURI()方法。当使用“媒体”等进行调用时,这将返回“http://search.yahoo.com/mrss/”
xPath.setNamespaceContext(new NamespaceContext() {
@Override
public String getNamespaceURI(String prefix) {
return doc.lookupNamespaceURI(prefix);
}
@Override
public Iterator<?> getPrefixes(String arg0) {
return null;
}
@Override
public String getPrefix(String arg0) {
return null;
}
});