使用Woodstox / Stax2编写XML时验证失败

时间:2016-05-18 13:36:29

标签: java xml xsd stax woodstox

我在使用带有Woodstox和Stax2的XSD架构进行XML验证时遇到问题。即使XML数据符合架构,验证也会失败。

令人惊讶的是,验证问题仅在编写 XML(使用XMLStreamWriter2)时发生,而不是在读取 XML(使用XMLStreamReader2)时发生。

我已经构建了一个小例子来重现和隔离错误。 基本上,它只是将文件中的XML读入XMLStreamReader2(使用XSD架构进行验证),然后将其复制到XMLStreamWriter2(也使用相同的XSD进行验证)。

现在,由于 writer 的验证错误而失败。如果我在编写器上停用验证,一切顺利,编写器提供完全符合的XML。

以下是代码:

import com.ctc.wstx.stax.WstxInputFactory;
import com.ctc.wstx.stax.WstxOutputFactory;
import org.codehaus.stax2.XMLStreamReader2;
import org.codehaus.stax2.XMLStreamWriter2;
import org.codehaus.stax2.validation.XMLValidationSchema;
import org.codehaus.stax2.validation.XMLValidationSchemaFactory;

import javax.xml.stream.XMLStreamException;
import java.io.InputStream;
import java.io.StringWriter;

public class Converter {

    public static void main(String... args) throws XMLStreamException {

        InputStream reader = Converter.class.getClassLoader().getResourceAsStream("test.xml");
        StringWriter writer = new StringWriter();

        XMLValidationSchema schema = XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA)
                .createSchema(Converter.class.getClassLoader().getResourceAsStream("schema.xsd"));


        XMLStreamReader2 xmlReader = (XMLStreamReader2) new WstxInputFactory().createXMLStreamReader(reader);
        xmlReader.validateAgainst(schema);

        XMLStreamWriter2 xmlWriter = (XMLStreamWriter2) new WstxOutputFactory().createXMLStreamWriter(writer);
        xmlWriter.validateAgainst(schema);

        xmlWriter.copyEventFromReader(xmlReader, false);

        while (xmlReader.hasNext()) {
            xmlReader.next();

            xmlWriter.copyEventFromReader(xmlReader, false);
        }

        System.out.println(writer.toString());
    }
}

这是XML:

<?xml version="1.0" encoding="UTF-8"?>
<JobStatus xsdVersion="NA">
    <Document>
        <DocumentId>1234567890</DocumentId>
    </Document>
    <Document>
        <DocumentId>1234567891</DocumentId>
    </Document>
</JobStatus>

这是架构:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="JobStatus">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Document" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="DocumentId" type="xs:string"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="xsdVersion" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>
</xs:schema>

这一切都导致了(启用了编写器的验证):

Exception in thread "main" com.ctc.wstx.exc.WstxValidationException: element "JobStatus" is missing "xsdVersion" attribute
        at [row,col {unknown-source}]: [1,66]
        at com.ctc.wstx.exc.WstxValidationException.create(WstxValidationException.java:50)
        at com.ctc.wstx.sw.BaseStreamWriter.reportProblem(BaseStreamWriter.java:1223)
        at com.ctc.wstx.msv.GenericMsvValidator.reportError(GenericMsvValidator.java:549)
        at com.ctc.wstx.msv.GenericMsvValidator.reportError(GenericMsvValidator.java:541)
        at com.ctc.wstx.msv.GenericMsvValidator.reportError(GenericMsvValidator.java:535)
        at com.ctc.wstx.msv.GenericMsvValidator.validateElementAndAttributes(GenericMsvValidator.java:343)
        at com.ctc.wstx.sw.BaseNsStreamWriter.closeStartElement(BaseNsStreamWriter.java:420)
        at com.ctc.wstx.sw.BaseStreamWriter.copyEventFromReader(BaseStreamWriter.java:807)
        at Converter.main(Converter.java:34)

如果没有对writer进行验证,程序运行正常并返回与输入相同的XML(模数缩进和换行差异)

所以我的问题是:我在这里做Woodstox有问题吗?为什么验证只在作者身上失败?

我可以使用其他XSD和XML对重现此问题,在这种情况下,您可以获得不同类型的错误,但总是在编写者方面。读者端的验证始终有效(只要XML明显符合XSD)。

非常感谢任何见解!

PS:供参考,以下是示例使用的依赖项和版本

  • org.codehaus.woodstox stax2-api 4.0.0
  • com.fasterxml.woodstox woodstox-core 5.0.2
  • net.java.dev.msv msv-core 2013.6.1
  • net.java.dev.msv xsdlib 2013.6.1&lt;

1 个答案:

答案 0 :(得分:0)

在写作时验证这是Woodstox中的一个错误:https://github.com/FasterXML/woodstox/issues/16

该问题现已在Woodstox 5.0.3版本中修复,但在写入验证时仍存在一些问题(请参阅https://github.com/FasterXML/woodstox/issues/23)。