2016-09-28 114 views
0

我想从此网站提取内容:https://it.projektwerk.com/de/projects/javax.xml.xpath的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文档中去除命名空间属性。但是这不是不是工作!令人惊讶的是,被测试的html文档的html标签内的xmlns属性只会改变它在属性列表中的位置。 所以将溶液手动删除的xmlns从使用HTML节点的HtmlCleaner的TagNode代表性htmlTag属性:

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

删除此,在问题中定义的XPath表达式将返回所希望的结果。