我在Envelope
使用这段代码(如下)验证此 SOAP 时遇到问题。
我得到的错误是:
org.xml.sax.SAXParseException;cvc-elt.4.2:无法将“ipo:UKAddress”解析为元素“shipTo”的类型定义。
SOAP XSD 定义Body
为:
<xs:complexType name="Body">
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
</xs:sequence>
我的期望是“宽松”应该验证它是否有定义,但如果没有定义则忽略。但是,对于xsi:type="ipo:UKAddress"
. 我只验证 SOAP Envelope
- 而不是Body
.
它看起来像 xerces-j 中的一个错误。在同一段代码中,XMLSchemaValidator.java :2152 实际上会在引发错误之前检查 processContents:
else if (wildcard != null && wildcard.fProcessContents == XSWildcardDecl.PC_STRICT) {
然而,XMLSchemaValidator.java :2178 没有进行此类检查,并且无论如何都会抛出。
fCurrentType = getAndCheckXsiType(element, xsiType, attributes);
对我来说,它看起来像是 xerces-j 中的一个错误。此外,Java 8 中存在此问题。感谢任何帮助或确认这确实是一个错误。
package com.example.xmlvalidate;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.CodeSource;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class Validate {
private static final String envelope =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<soapenv:Envelope \n" +
" xmlns=\"http://www.w3.org/2001/XMLSchema\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
" >\n" +
" <soapenv:Body>\n" +
" <ipo:purchaseOrder xmlns:ipo=\"http://www.example.com/IPO\">\n" +
" <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">\n" +
" <name>Helen Zoe</name>\n" +
" <street>47 Eden Street</street>\n" +
" <city>Cambridge</city>\n" +
" <postcode>CB1 1JR</postcode>\n" +
" </shipTo>\n" +
" </ipo:purchaseOrder>\n" +
" </soapenv:Body>\n" +
"</soapenv:Envelope>";
private static final String SOAP_1_1_ENVELOPE =
"http://schemas.xmlsoap.org/soap/envelope";
protected static final String W3C_XML_SCHEMA =
"http://www.w3.org/2001/XMLSchema";
public static void validate() throws ParserConfigurationException, SAXException, IOException, TransformerException {
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
documentBuilderFactory.setValidating(false);
final Class<?> clazz = documentBuilderFactory.getClass();
final CodeSource source = clazz.getProtectionDomain().getCodeSource();
System.out.println("Document builder implementation: " + clazz.getName() + " from : " + (source == null ? "JRE" : source));
final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
final InputStream is = new ByteArrayInputStream(envelope.getBytes(StandardCharsets.UTF_8));
final Document document = documentBuilder.parse(is);
final DOMSource domSource = new DOMSource(document);
final StreamSource streamSource = new StreamSource(new URL(SOAP_1_1_ENVELOPE).openStream());
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final Schema schema = schemaFactory.newSchema(streamSource);
final Validator validator = schema.newValidator();
validator.validate(domSource);
}
}