我在使用带有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:供参考,以下是示例使用的依赖项和版本
答案 0 :(得分:0)
在写作时验证这是Woodstox中的一个错误:https://github.com/FasterXML/woodstox/issues/16
该问题现已在Woodstox 5.0.3版本中修复,但在写入验证时仍存在一些问题(请参阅https://github.com/FasterXML/woodstox/issues/23)。