SAXParseException - 不允许属性;但只有在jboss

时间:2014-03-19 13:53:38

标签: xml jboss xsd saxparser

我有一个非常简单的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文件因为它可能会破坏其他东西

1 个答案:

答案 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

的xml
unmarshaller = getJaxbContext().createUnmarshaller();
        if(getRequest().isResponseStrict()) {
            unmarshaller.setSchema(getSchema());
        }
        return (ResponseType)unmarshaller.unmarshal(getXmlInputStream());