0

我有一个 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();
        }
4

3 回答 3

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)。

于 2012-08-24T16:12:44.983 回答
0

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

于 2012-08-24T15:49:46.830 回答
0

您是否尝试过为 SOAP-ENV 使用以下 URI?

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

于 2012-08-24T13:11:12.897 回答