2013-05-20 3 views
3

Я использую XPath для анализа XML-документа, возвращаемого URL-адресом, когда я запускаю свой код с данными вводами, но он работает, но когда он вводит данные как пользовательский ввод, он выдает исключение. Кодекс:Невозможно оценить выражение в 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

Это XML-документ, созданный dom –

+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

Это * вероятно * правильно, но ОП на самом деле не содержит достаточно информации, чтобы знать наверняка. –

+0

Я уже сделал это, что-то имя класса NameSpaceResolver - это просто имяSpaces в моем коде –

+0

@Brass Block: Возможно, вы также можете показать нам XML. Имеет ли xml правильные объявления пространства имен? – User0

6

Исключение "Невозможно вычислить выражение, используя этот контекст" может также возникнуть из документа null при попытке оценить выражение XPath. (У меня была такая же ошибка, и мне потребовалось некоторое время, чтобы понять, что я не правильно инициализировал свой документ).

В своем коде вы имеете

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

Да, в моем случае ошибка была вызвана нулевым документом. Это было результатом ошибки в восходящем потоке. Благодарю. –