Xpath cannot request namespace tag

I have xml as shown below (Google API) but cannot get the value of the gphoto:id element. How to do it? Note. When I use domFactory.setNamespaceAware(true); , /feed/entry xpath stops working.

 <?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> 

Java

 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("", "", "")); } 

way method

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

SOLVED according to @gioele path() answer now looks like this:

 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; } 
+4
source share
2 answers

Before compiling xpath, you need to register a NamespaceContext .

Look at the code at https://github.com/gioele/xpathapi-jaxp/blob/master/src/main/java/it/svario/xpathapi/jaxp/NodeNamespaceContext.java .

If you want to avoid all these complications, you can use the 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); } 

Disclaimer: I am the creator of XPathAPI-JAXP.

+3
source

An easier way to deal with the namespace problem is to simply redirect the call from the NamespaceContext to the lookupNamespaceURI () method of the document. This will be returned "http://search.yahoo.com/mrss/" when called from "media", etc.

 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; } }); 
+3
source

Source: https://habr.com/ru/post/1395568/


All Articles