2012-08-24 28 views
0

我有一個xml文件,它是來自Webservice的響應。它有各種與它有關的名稱空間。當我嘗試使用適當的XSD驗證它時,拋出「org.xml.sax.SAXParseException:cvc-elt.1:找不到元素'SOAP-ENV:Envelope'的聲明。」所有名稱空間的名稱空間聲明都在響應中聲明。 以下是我的代碼具有名稱空間的XML使用XSD進行驗證會拋出異常

try { 
     DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); 
      SchemaFactory schemaFactory = SchemaFactory 
      .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
      SAXSource mainInputStream = new SAXSource(new InputSource(new FileInputStream(new File("FIXEDINCOME_v3_0.xsd")))); 
      SAXSource importInputStream1 =new SAXSource(new InputSource(new FileInputStream(new File("Rating.xsd")))); 
      SAXSource importInputStream2 = new SAXSource(new InputSource(new FileInputStream(new File("Datatypes.xsd")))); 
      Source[] sourceSchema = new SAXSource[]{mainInputStream , importInputStream1, importInputStream2}; 
      Schema schema = schemaFactory.newSchema(sourceSchema); 
      xmlFact.setNamespaceAware(true); 
      xmlFact.setSchema(schema); 
      DocumentBuilder builder = xmlFact.newDocumentBuilder(); 
      xmlDOC = builder.parse(new InputSource(new StringReader(inputXML))); 
      NamespaceContext ctx = new NamespaceContext() { 
       public String getNamespaceURI(String prefix) { 
        String uri; 
        if (prefix.equals("ns0")) 
         uri = "http://namespace.worldnet.ml.com/EDS/Standards/Common/Service_v1_0/"; 
        else if (prefix.equals("ns1")) 
         uri = "http://namespace.worldnet.ml.com/EDS/Product/Services/Get_Product_Data_Svc_v3_0/"; 
        else if (prefix.equals("ns2")) 
         uri = "http://namespace.worldnet.ml.com/DataSOA/Product/Objects/FixedIncome/FixedIncome_v3_0/"; 
        else if (prefix.equals("ns3")) { 
         uri = "http://namespace.worldnet.ml.com/DataSOA/Product/Objects/Rating/Rating_v2_0/"; 
        } else if (prefix.equals("SOAP-ENV")) { 
         uri = "http://schemas.xmlsoap.org/soap-envelope/"; 
        } else 
         uri = null; 

        return uri; 
       } 

       // Dummy implementation - not used! 
       public Iterator getPrefixes(String val) { 
        return null; 
       } 

       // Dummy implemenation - not used! 
       public String getPrefix(String uri) { 
        return null; 
       } 
      }; 

      XPathFactory xpathFact = XPathFactory.newInstance(); 
      xPath = xpathFact.newXPath(); 
      xPath.setNamespaceContext(ctx); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
+2

對於這些類型的問題,張貼xml是必須的 –

+0

XML對我來說太大了,無法發佈。這實際上是一個普遍問題。 XSD驗證程序無法識別名稱空間變量。 – mavrav

+0

這裏的問題是,我將如何讓DOM解析器知道XML具有名稱空間。? – mavrav

回答

0

設定您所提供的驗證不包括SOAP模式架構的。您可以在模式集合中包含soap模式,或者如果您不關心驗證soap包裝器,只需抓住實際的body內容元素並從那裏運行驗證。

+0

謝謝你。試過,但它仍然拋出相同的異常[錯誤]:1:57:cvc-elt.1.a:找不到元素'FixedIncome'的聲明。 FixedIncome是父元素 – mavrav

+0

@mavrav - 實際上,不,這是一個不同的例外。我給了2個建議,你試過了嗎? – jtahlborn

1

我不認爲問題是檢測SOAP-ENV前綴的名稱空間定義。驗證程序需要XSD文件來定義在該名稱空間中使用的元素,以驗證SOAP-ENV:Envelope元素,因此您需要告訴驗證程序該模式所在的位置。

我認爲解決的辦法是要麼以下添加到您的XML的回覆:

<SOAP-ENV:Envelope 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsi="http://schemas.xmlsoap.org/soap/envelope/" 
    xsi:schemaLocation="http://schemas.xmlsoap.org/soap/envelope/  
      http://schemas.xmlsoap.org/soap/envelope/"> 

或者去下載該模式關閉網頁,將其保存到本地文件系統作爲一個XSD文件,並將其添加到你的sourceSchema陣列。第一種方法應該是首選的,因爲它導致更便攜的代碼(和XML)。

+0

對於本地不可用的模式運行任何生產驗證是一個壞主意。您不希望生產系統停止工作,因爲遠程託管資源由於某種原因不可用(更不用說潛在的安全問題)。 – jtahlborn

+0

在Web上發佈不引用公共可用模式(如果它們旨在進行驗證)的東西也是一個壞主意。如同任何工程問題,也有雙方很好的理由,你必須要考慮的權衡,並作出決定適合您的應用程序。 – Alex

+0

肯定引用了命名空間,但是不,我不同意你需要引用公共可用的模式位置。只是鼓勵人們使用它,它,就像我已經說過的,是一個壞主意。當然,將圖案放在公共場所供人下載當然是一個好主意。 – jtahlborn