我有一个非常简单的xsd文件
<xs:element name="SummaryStatus">
<xs:complexType>
<xs:attribute name="cnt" type="xs:int" use="required"></xs:attribute>
<xs:attribute name="err" type="xs:int" use="optional" default="0"></xs:attribute>
</xs:complexType>
</xs:element>
我用它来验证这个xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<SummaryStatus cnt="1" />
anywawy,当我在单元测试中运行验证时,验证本身有效,一切都按预期完成,验证显然使用了来自 com.sun.org.apache.xerces的xml解析器等。* 来自\ Java \ jdk1.7.0_51 \ jre \ lib \ rt.jar
当我将整个内容部署到jboss时,它使用来自jboss-4.2.3.GA \ lib \ endorsed \ xercesImpl.jar的 org.apache.xerces。* ,我得到此异常< / p>
Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 63; cvc-complex-type.3.2.2: Attribute 'cnt' is not allowed to appear in element 'SummaryStatus'.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.processAttributes(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
at org.apache.xerces.jaxp.validation.ValidatorHandlerImpl.startElement(Unknown Source)
at com.sun.xml.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:89)
at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:71)
at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:137)
at org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:551)
at at.apa.commons.webservice.http.xml.JaxbXmlResponseStrategy$NamespaceFilter.startElement(JaxbXmlResponseStrategy.java:188)
at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.emptyElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentScannerImpl$ContentDispatcher.scanRootElementHook(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:357)
我的验证/解组代码归结为此
XMLFilter filter = new NamespaceFilter(getXmlns());
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
filter.setParent(xmlReader);
unmarshaller = jaxbContext.createUnmarshaller();
Schema schema = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema").newSchema(getSchemaLocation());
unmarshaller.setSchema(schema);
UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
filter.setContentHandler(unmarshallerHandler);
InputSource xml = getInputSource();
filter.parse(xml);
return (ResponseType)unmarshallerHandler.getResult();
,其中
getXmlns() = "http://apa.at/powersearch/inputservice/SummaryStatus"
and
getSchemaLocation() = SummaryStatus.class.getClassLoader().getResource("schema/SummaryStatus.xsd")
我使用getResource获取的模式文件的url是有效的并且可以正确解析(我尝试在url上打开输入流并在jboss中运行时读取模式并且可以正常工作 - 因此架构正在正确加载)
,过滤器看起来像
protected static class NamespaceFilter extends XMLFilterImpl {
private final String xmlns;
public NamespaceFilter(String xmlns) {
this.xmlns = xmlns;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(xmlns, localName, qName);
}
@Override
public void startElement(String uri, String localName,
String qName, Attributes atts) throws SAXException {
super.startElement(xmlns, localName, qName, atts);
}
}
我正在使用这个过滤器,因为我从Web服务获取的xml没有xmlns声明,所以我&#34;注入&#34;它手动,所以我可以根据模式验证它 - 再次这完全正常(使用com.sun的东西,但失败的jboss类)
我尝试使用maven repo中的版本2.0+更新我的jboss中的xercesImpl.jar,但这只会在启动服务器时导致一堆异常,而且我真的不想开始切换jar文件因为它可能会破坏其他东西
答案 0 :(得分:1)
我最终做的是将架构文件更改为
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="SummaryStatus">
<xs:complexType>
<xs:attribute name="cnt" type="xs:int" use="required"></xs:attribute>
<xs:attribute name="err" type="xs:int" use="optional" default="0"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
在schema元素包含xmlns和targetNamespace声明之前,现在已经不再这样了,它希望我验证的 not 的xml元素无论如何都在命名空间中,我可以解组带有简单的unmarshaller + schema
的xmlunmarshaller = getJaxbContext().createUnmarshaller();
if(getRequest().isResponseStrict()) {
unmarshaller.setSchema(getSchema());
}
return (ResponseType)unmarshaller.unmarshal(getXmlInputStream());