XPath

2013-05-20 2 views
3

I에서 표현식을 평가할 수 없습니다. URL에 의해 반환 된 XML 문서를 구문 분석하기 위해 XPath를 사용합니다. 주어진 입력으로 코드를 실행할 때 작동하지만 사용자 입력으로 입력 할 때 예외가 발생합니다. 강령 :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

제 경우에는 오류가 null 문서 때문이었습니다. 이는 업스트림 버그의 결과였습니다. 감사. –