2013-05-20 183 views
3

我使用XPath解析由URL返回的XML文檔,當我使用給定的輸入運行我的代碼時,它將輸入作爲用戶輸入時發出異常。 守則:無法評估XPath中的表達式

class{ 
     private String generalQuery = "//@*"; 
    method(){ 
     System.out.println("Enter URL"); 
     url = scan.nextLine(); 
     URL oracle = new URL(url); 
     InputStream is = oracle.openStream(); 

     org.w3c.dom.Document doc = null; 
     DocumentBuilderFactory domFactory; 
     DocumentBuilder builder; 

     try { 
      domFactory = DocumentBuilderFactory.newInstance(); 
      domFactory.setNamespaceAware(true); 
      builder = domFactory.newDocumentBuilder(); 
      doc = builder.parse(is); 
     } catch (Exception ex) { 
      System.err.println("unable to load XML: " + ex); 
     } 

    Map <String, String> params = new HashMap<String, String>(); 

      XPathFactory factory = XPathFactory.newInstance(); 
      XPath xpath = factory.newXPath(); 
      xpath.setNamespaceContext(new NameSpaces(doc)); 
      XPathExpression expr = xpath.compile(generalQuery); 
      Object result = expr.evaluate(doc, XPathConstants.NODESET); // exception thrown here 

      NodeList nl = (NodeList) result; 

      for (int i = 0 ; i < nl.getLength() ; i++){ 
       Node n = (Node)nl.item(i); 
       params.put(n.getNodeName(), n.getNodeValue()); 
      } 

      return params; 
} 
} 

例外:

javax.xml.transform.TransformerException: Unable to evaluate expression using this context 

類的命名空間:

import java.util.Iterator; 
import javax.xml.XMLConstants; 
import javax.xml.namespace.NamespaceContext; 
import org.w3c.dom.Document; 

public class NameSpaces implements NamespaceContext { 
    private Document sourceDocument; 

    public NameSpaces(Document document) { 
     sourceDocument = document; 
    } 

    @Override 
    public String getNamespaceURI(String prefix) { 
     if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) { 
      return sourceDocument.lookupNamespaceURI(null); 
     } else { 
      return sourceDocument.lookupNamespaceURI(prefix); 
     } 
    } 

    @Override 
    public String getPrefix(String namespaceURI) { 
     return sourceDocument.lookupPrefix(namespaceURI); 
    } 

    @Override 
    public Iterator<String> getPrefixes(String namespaceURI) { 
     return null; 
    } 
} 
+0

這段代碼中的'doc'類型是什麼? –

+0

它是由dom創建的XML文檔 –

+0

什麼是'NameSpaces'? 'setNamespaceContext'方法需要一個'NamespaceContext'類型的參數。正如@Ian指出的,你也沒有告訴我們'doc'的類型。正如所寫的,你的問題甚至不會編譯,你已經讓我們猜測你應該包括的東西。 –

回答

0

你似乎什麼是失蹤是NameSpaceContext,你可以實施你自己。

也看到這個線程:NamespaceContext and using namespaces with XPath

例子:

class NamespaceResolver implements NamespaceContext { 

    private final Document document; 

    public NamespaceResolver(Document document) { 
     this.document = document; 
    } 

    public String getNamespaceURI(String prefix) { 
     if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) { 
      return document.lookupNamespaceURI(null); 
     } else { 
      return document.lookupNamespaceURI(prefix); 
     } 
    } 

    public String getPrefix(String namespaceURI) { 
     return document.lookupPrefix(namespaceURI); 
    } 

    @SuppressWarnings("rawtypes") 
    public Iterator getPrefixes(String namespaceURI) { 
     // not implemented 
     return null; 
    } 

} 

然後你開始這樣的XPath的實例:

getXPath().setNamespaceContext(new NamespaceResolver(doc)); 
+0

這可能是正確的,但OP沒有包含足夠的信息來確認。 –

+0

我已經這樣做了,其中的一些是NameSpaceResolver的名字就是我的代碼中的NameSpaces –

+0

@Brass Block:也許你也可以向我們展示XML。 xml是否有適當的名稱空間聲明? – User0

6

異常 「無法使用此背景下,以評估表達」在嘗試評估XPath表達式時,也可能由null文檔引起。 (我有同樣的錯誤,並花了我一段時間才弄清楚我沒有正確初始化我的文檔)。

在你的代碼有

try { 
    // load document 
} 
catch (Exception ex) { 
    System.err.println("unable to load XML: " + ex); 
} 

// happily continue 

這是一個麻煩的電話。如果在初始化期間發生異常,您應該立即停止,並且不應繼續。如果您完全不知道如何處理錯誤,請使用catch(Exception e) { throw new Error(e); }。這將導致異常冒泡並希望由默認異常處理程序處理,該異常處理程序打印堆棧跟蹤並退出。

作爲你的問題的讀者,我甚至不知道拋出異常的位置。你應該提供這些信息。請注意,您也可以使用someException.printStackTrace();來獲取指向正確行的堆棧跟蹤。

+0

是的,在我的情況下,錯誤是由於空文檔。這是上游臭蟲的結果。謝謝。 –