2016-09-28 9 views
0

Я хочу, чтобы извлечь содержимое этого сайта: https://it.projektwerk.com/de/projects/выражение XPath для javax.xml.xpath не работает

например У меня есть выражение XPath: .//*[@id='content_0']/H3/A (Обратите внимание, что заглавные буквы правильно, так как мой документ-парсер -> org.cyberneko.html ... разбирают тег в этих заглавных)

Это правильное выражение XPath ; Например, я могу получить контент, используя FirePath. Однако, используя классы javax.xml.xpath, поиск невозможен. Я делаю это так:

XPath xpath = XPathFactory.newInstance().newXPath(); 
XPathExpression expr = xpath.compile(exprString); 
Node node = expr.evaluate(doc, XPathConstants.NODE); 

но node всегда null.

Я не понимаю этого, как есть и другие веб-сайты с другими выражениями одного и того же синтаксиса, где это работает (например, .//*[@id='p_p_id']/DIV/DIV/DIV/DIV[3]/A/H3/SPAN)

Надежда кто-то может помочь.

+1

Обычно элементы HTML находятся в пространстве имен HTML, то есть в пространстве имен, URI которого «http: // www.w3.org/1999/xhtml». Вам нужно будет вызвать [xpath.setNamespaceContext] (http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPath.html#setNamespaceContext-javax.xml.namespace.NamespaceContext-), чтобы сделать это пространство имен известным механизму XPath, затем измените ваше выражение на нечто вроде './/*[@ID = 'content_0']/html: H3/html: A'. – VGR

+0

Спасибо VGR, что помогло мне добраться до решения, см. Мой ответ ниже для деталей. – eSKape

ответ

0

Благодаря VGR я смог узнать о проблеме. Веб-сайт, где это Xpath выражение не работало, был пространство имен известен сайтом с HTML теге сконструированного так:

Как я использую HtmlCleaner, я использовал следующий код:

HtmlCleaner cleaner = new HtmlCleaner(); 
CleanerProperties props = cleaner.getProperties(); 
props.setNamespacesAware(false); 
TagNode mainNode = cleaner.clean(htmlString); 

, который должен , в соответствии с документацией, разделите атрибуты пространства имен из html-документа. Но это нет работа! Удивительно, что атрибут xmlns внутри тега html тестируемого html-документа только изменит его положение внутри списка атрибутов. Таким образом, решение было вручную удалить атрибут XMLNS из HtmlTag с использованием TagNode представления HtmlCleaner по HTML-узел:

public TagNode removeNamespaceFromHtmlTag(TagNode htmlNode) { 
    htmlNode.removeAttribute("xmlns"); 
    return htmlNode; 
} 

Удаления этого выражение XPath определенно в вопросе будет возвращать желаемый результат.