2012-05-23 85 views
7

我想做的事情在這個文件中的XPath查詢(如圖所示節選):的Java的XPath:與默認命名空間的xmlns查詢

<?xml version="1.0" encoding="UTF-8"?> 
<!-- MetaDataAPI generated on: Friday, May 25, 2007 3:26:31 PM CEST --> 
<ModelClass xmlns="http://xml.sap.com/2002/10/metamodel/webdynpro" xmlns:IDX="urn:sap.com:WebDynpro.ModelClass:2.0"> 
    <ModelClass.Parent> 
     <Core.Reference package="com.test.mypackage" name="ModelName" type="Model"/> 

這是代碼片段我使用:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder builder = domFactory.newDocumentBuilder(); 
Document document = builder.parse(new File(testFile)); 
XPathFactory factory = XPathFactory.newInstance(); 
XPath xpath = factory.newXPath(); 
xpath.setNamespaceContext(new NamespaceContext() { 
    public String getNamespaceURI(String prefix) { 
... 

String result = xpath.evaluate(xpathQueryString, document); 
System.out.println(result); 

我面臨的問題是,當在XPath查詢中引用默認命名空間時,不會調用getNamespaceURI方法來解決它。 該查詢例如不提取任何東西:

//xmlns:ModelClass.Parent/xmlns:Core.Reference[@type=\"Model\"]/@package

現在,通過用假前綴d更換xmlns,然後相應地寫getNamespaceURI方法我已經試過「欺騙」的解析器(所以返回http://xml.sap.com/2002/10/metamodel/webdynpro遇到d時)。在這種情況下,將調用getNamespaceURI,但XPath表達式評估的結果始終爲空字符串。

如果我從文件和XPath查詢表達式中去除命名空間,我可以得到我想要的字符串(com.test.mypackage)。

有沒有辦法使事情與默認名稱空間正常工作?

回答

8

在你Namespace上下文中,(例如df)結合前綴您選擇的命名空間URI的文檔中

xpath.setNamespaceContext(new NamespaceContext() { 
    public String getNamespaceURI(String prefix) { 
     switch (prefix) { 
     case "df": return "http://xml.sap.com/2002/10/metamodel/webdynpro"; 
     ... 
     } 
    }); 

,然後使用該前綴在路徑表達式以例如限定元素名稱/df:ModelClass/df:ModelClass.Parent/df:Core.Reference[@type = 'Model']/@package

+0

嗨馬丁,我試過了,但它不起作用... –

+4

請確保您還創建了名稱空間感知DocumentBuilder http://docs.oracle.com/javase/6/docs/api/javax/ xml/parsers/DocumentBuilderFactory.html#setNamespaceAware%28boolean%29在使用命名空間之前。 –

+0

這個技巧。我認爲DocumentBuilder默認是知道命名空間的。再次感謝你。 –

10

XPath 1.0規範要求「沒有前綴表示沒有名稱空間」。因此,爲XPath 1.0設計的JAXP非常適合阻止您將「空前綴」綁定到某些非空名稱空間。

XPath 2.0允許您爲XPath表達式中的非限定名稱聲明一個默認名稱空間,但要充分利用這一點,您將需要一個利用此功能的API(如Saxon的s9api)。

+0

謝謝邁克爾的額外信息。 –

相關問題