Парсинг атома: поле ссылки в XML с XPath из Play.libs - PullRequest
0 голосов
/ 05 августа 2011

Я работаю над веб-приложением на Paly! Фреймворк. Я должен разобрать документ XML. Я использую XPath из Play.libs.

Вот часть документа, которую мне не удалось найти:

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

И кусок кода, который я написал.

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)

Я тоже пробовал

* * 1010

И не удалось, и вернул ноль.

изменить: Я обнаружил в сети (здесь) , что эта проблема может исходить от DocumentBuilder (документ не знает о пространствах имен). И все же я его не создавал, это стандартный ответ в Openstack Compute API. это означает, что я не контролирую его построение.

если вы хотите увидеть полный XML-документ: здесь

edit2: Похоже, у меня «проблема, не связанная с пространством имен», есть предложения, чтобы избежать этой проблемы?

Ответы [ 2 ]

0 голосов
/ 08 августа 2011

Для тех, кто имеет или будет иметь ту же проблему, я напишу здесь решение, которое я выбрал.

Поскольку проблема исходит от построителя документов, и эта функция getXml не устанавливает для документа осведомленность о пространствах имен, вам необходимо заменить эту функцию.

Код от маяк :

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

И вместо получения вашего DOM-документа вот так:

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

Вы должны использовать вместо:

getXml(WS.url("http://www.yoursource.com").get(),"UTF-8"); 
0 голосов
/ 05 августа 2011

Обратите внимание, что выражение XPath относится к контексту, в вашем случае к узлу документа.Ваше выражение выбирает всеэлементы, которые являются прямыми потомками документа (и, конечно же, их нет).Вам нужно либо указать полный путь к нужному элементу связи атомов, либо использовать некоторый предикат, который однозначно его идентифицирует.

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

выберетэлемент с rel = self содержится в первом элементе .

ОБНОВЛЕНИЕ:

Если у вас есть проблема с пространством имен,

xmlDoc.getRootElement.getNamespaceURI()

должен вернуть ноль.В этом случае легко обойти использование тестового кода, найденного в отчете об ошибке выше.

...