2013-12-21 2 views
1

У меня есть проблема с jdom2 XPath:неясные результаты с jdom2 XPath запроса

test.xhtml код:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs" lang="cs"> 
<head> 
<title>mypage</title> 
</head> 
<body> 
<div class="in"> 
<a class="nextpage" href="url.html"> 
<img src="img/url.gif" alt="to url.html" /> 
</a> 
</div> 
</body> 
</html> 

Java код:

Document document; 
SAXBuilder saxBuilder = new SAXBuilder(); 

document = saxBuilder.build("test2.html"); 
XPathFactory xpfac = XPathFactory.instance(); 
XPathExpression<Element> xp = xpfac.compile("//a[@class = 'nextpage']", Filters.element()); 
for (Element att : xp.evaluate(document)) { 
    System.out.println("We have target " + att.getAttributeValue("href")); 
} 

Но как раз с этим я не могу получить любой элемент. Я обнаружил, что когда запрос //*[@class = 'nextpage'], он находит его.

We have target url.html 

Это должно быть что-то с пространством имен или чем-то другим в заголовке, потому что без него он может генерировать некоторый вывод. Я не знаю, что я делаю неправильно.

+0

«Это должно быть что-то с пространством имен» - правильно. «Возможный дублирующий» вопрос, с которым я связался, был первым хитом, который дал мне Google для «пространства имен jdom xpath» –

+0

теперь решена - изменения: пространство имен пространства имен = пространство имен.Namespace («my», «http: //www.w3 .org/1999/XHTML "); и XPathExpression xp = xpfac.compile ("// my: a [@class = 'nextpage']", Filters.element(), null, пространство имен); – d3im

+1

Этот вопрос кажется не по теме, потому что он теперь _solved_ (см. Комментарий OP). – devnull

ответ

0

Примечание: Хотя это та же проблема, что и в предлагаемом дубликате, этот другой вопрос относится к версиям JDOM 1.x. В JDOM 2.x есть ряд существенных отличий. Этот ответ относится к реализации JDOM 2.x XPath which is significantly different.

Спецификация XPath очень понятна в отношении того, как пространства имен обрабатываются в выражениях XPath. К сожалению, для людей, знакомых с XML, обработка XPath для Namespaces несколько отличается от ожидаемых. This is the specification:

QName в тесте узла расширено в расширенное имя, используя объявления пространства имен из контекста выражения. Точно так же выполняется расширение для имен типов элементов в начальных и конечных тегах, за исключением того, что пространство имен по умолчанию, объявленное с помощью xmlns, не используется: если QName не имеет префикса, тогда URI пространства имен имеет значение NULL (это то же самое имена атрибутов пути). Это ошибка, если в QName есть префикс, для которого нет объявления пространства имен в контексте выражения.

На практике это означает, что в любое время, когда у вас есть пространство имен по умолчанию в вашем XML-документе, вам все равно необходимо префикс этого пространства имен при использовании его в выражении XPath. Метод XPathFactory.compile (...) ссылается на это требование in the JavaDoc, но это не так ясно, как должно быть. Префикс, который вы используете, является произвольным и локальным только для этого выражения XPath. В вашем случае код будет выглядеть примерно так (при условии, мы выбираем пространство имен xhtml для URI http://www.w3.org/1999/xhtml):

XPathFactory xpfac = XPathFactory.instance(); 
Namespace xhtml = Namespace.getNamespace("xhtml", "http://www.w3.org/1999/xhtml"); 
XPathExpression<Element> xp = xpfac.compile("//xhtml:a[@class = 'nextpage']", Filters.element(), null, xhtml); 
for (Element att : xp.evaluate(document)) { 
    System.out.println("We have target " + att.getAttributeValue("href")); 
} 

Я должен добавить это в FAQ ... Спасибо.

Смежные вопросы