2016-09-28 40 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表達式將返回所希望的結果。