我想解析由XOM的外部系統返回的一些HTML。該HTML如下:(其實它顯著理出頭緒,但它有這個DOCTYPE聲明,這些名字空間和語言的聲明,以上展品HTML同樣的問題,因爲真正的HTML)使用XPath從具有不必要的命名空間的文檔中提取XOM元素
<!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="en" lang="en">
<body>
<div>
Help I am trapped in a fortune cookie factory
</div>
</body>
</html>
我想要做的是提取<div>
的內容,但命名空間聲明似乎令XPath變得令人困惑。如果我帶出空間聲明(用手,從文件),下面的代碼查找<div>
,沒問題:
Document document = ...
Nodes divs = document.query("//div");
但與命名空間,返回Nodes
的大小爲0。
好的,如果我以編程方式剝離命名空間,怎麼樣?
Element rootElement = document.getRootElement();
rootElement.removeNamespaceDeclaration(rootElement.getNamespacePrefix());
...看起來應該可以工作,但什麼都不做。從javadoc:
此方法僅刪除與
addNamespaceDeclaration.
好增加額外的命名空間,我想,我會提供命名空間查詢:
XPathContext context =
XPathContext.makeNamespaceContext(document.getRootElement());
Nodes divs = document.query("//div", context);
大小仍爲零。
如何手動構建名稱空間上下文?
XPathContext context = context = new XPathContext(
rootElement.getNamespacePrefix(), rootElement.getNamespaceURI());
Nodes divs = document.query("//div", context);
的XPathContext
構造吹了:
nu.xom.NamespaceConflictException:
XPath expressions do not use the default namespace
所以,我在尋找之一:
- 一個方法,使這項工作查詢,或
- 方式以編程方式剝離名稱空間聲明或
- 解釋正確的a pproach,假設這兩個都是錯誤的。
更新:基於上Lev Levitsky's answer和Jaxen FAQ我想出了下面的技巧:
XPathContext context = new XPathContext(
"foo",
document.getRootElement().getNamespaceURI());
Nodes divs = document.query("//foo:div");
這仍似乎有點瘋狂的給我,但我想它的方式Jaxen的要你做事。
更新#2:正如下面和all over the Internet指出,這不是Jaxen的的錯;它只是XPath的XPath。
所以,雖然這個黑客的作品,我仍然喜歡一種方式來剝離命名空間聲明。最好不要XSLT。
這是XPath的工作原理與命名空間的方式,它不依賴於Jaxen的:如果你想匹配與命名空間的東西,你必須在XPath – MiMo 2012-03-13 01:21:33
使用一個明確的前綴是的,在進一步的閱讀中我看到了。所以,好吧,Jaxen沒有責備,但它似乎仍然有點瘋狂。或者,充其量是迂腐的,主要是爲了在不切實際的用例中達到最大的正確性。 – 2012-03-14 23:17:54