开发者

Parsing atom:link field in XML with XPath from Play.libs

I'm working on a web application on Paly! Framework. I have to parse a XML document. I'm using XPath from Play.libs.

Here is the piece of Document, I don't succeed to retrieve :

<atom:link rel="self" href="http://mylink.com/">

And the piece of code i wrote.

import java.util.Map;
import java.util.HashMap;
import org.w3c.dom.*;    
import play.libs.XPath;
import play.libs.WS;
import play.libs.ws.*;

WS.HttpResponse response = // I retrieve a Http response
Document xmlDoc = response.getXml();
Map<String,String> namespaces = new HashMap<String,String>(){{put("atom", "http://www.w3.org/2005/Atom");}}
Node link = XPath.selectNode("atom:link", xmlDoc, namespaces)

I also tried

Node link = XPath.selectNode("link", xmlDoc, namespaces)

Both failed and returned null.

edit : I found on the web (here) that this problem may come from the DocumentBuilder (document not aware of namespaces). Yet I didn't build it, it is a standart response in the Opensta开发者_如何学Cck Compute API. meaning that I have no control on the way it is built.

if you want to see the complete xml Document : here

edit2 : Looks like I have a 'not namespace aware problem', any suggestion to avoid that problem?


Note that XPath expression are relative to a context, in your case the document node. Your expression selects all <atom:link> elements that are direct children of the document (and, of course, there aren't any). You need to either specify the complete path to the desired atom link element, or use some predicate that uniquely identifies it.

"/os:servers/os:server[1]/atom:link[rel='self']"

would select an <atom:link> element with rel=self contained in the first <server> element.

UPDATE:

If you have the no namespace problem,

xmlDoc.getRootElement.getNamespaceURI()

should return null. In that case, it is easy to work around using the test code found in the bug report above.


For those who have or will have the same problem, i write here the solution i chose.

As the problem comes from the Document builder, and that getXml function does not set the document aware of namespaces, you have to replace that function.

Code from lighthouse :

public Document getXml(HttpResponse response, String encoding) {
    try {
        InputSource source = new InputSource(response.getStream());
        source.setEncoding(encoding);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
        factory.setNamespaceAware(true); 
        DocumentBuilder builder = factory.newDocumentBuilder();
        builder.setEntityResolver(new NoOpEntityResolver());
        return builder.parse(source);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

And instead of retrieving your DOM Document like that :

Document doc = WS.url("http://www.yoursource.com").get().getXml();

You should use instead :

getXml(WS.url("http://www.yoursource.com").get(),"UTF-8"); 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜