带名称空间的XML使用XSD进行验证会引发异常

时间:2012-08-24 12:57:37

标签: java xml xsd

我有一个xml文件,它是Webservice的响应。它有各种名称空间涉及它。当我尝试使用适当的XSD验证它时,它会抛出“org.xml.sax.SAXParseException:cvc-elt.1:找不到元素'SOAP-ENV:Envelope'的声明。”所有命名空间的名称空间声明都在响应中声明。 以下是我的代码

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();
        }

3 个答案:

答案 0 :(得分: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/">

或者,从Web下载该架构,将其作为XSD文件保存到本地文件系统,并将其添加到sourceSchema阵列。第一种方法应该是首选方法,因为它会带来更多可移植的代码(和XML)。

答案 1 :(得分:0)

您是否尝试过将以下URI用于SOAP-ENV?

http://schemas.xmlsoap.org/soap/envelope/

答案 2 :(得分:0)

您为验证提供的模式集不包括soap模式。您可以在架构集合中包含soap架构,或者,如果您不关心验证soap包装器,只需抓住实际的body内容元素并从那里运行验证。