Skip to content

Commit

Permalink
Reproducer for #179 WstxValidationException: Unknown reason (at end e…
Browse files Browse the repository at this point in the history
…lement </nl:nillableIntElement>) when validating a document with nillable elements (#180)
  • Loading branch information
ppalaga committed Nov 4, 2023
1 parent 06ef1c3 commit dbc4b99
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 0 deletions.
156 changes: 156 additions & 0 deletions src/test/java/wstxtest/msv/TestW3CSchemaNillable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package wstxtest.msv;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;

import javax.xml.XMLConstants;
import javax.xml.stream.*;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.codehaus.stax2.*;
import org.codehaus.stax2.validation.*;
import org.xml.sax.SAXException;

import wstxtest.vstream.BaseValidationTest;

/**
* Test whether MSV validator behaves the same w.r.t. nillable elements as javax.xml.validation validator.
* A reproducer for <a href="https://github.com/FasterXML/woodstox/issues/179">https://github.com/FasterXML/woodstox/issues/179</a>.
*/
public class TestW3CSchemaNillable
extends BaseValidationTest
{

public void testNillableDateTime() throws XMLStreamException, IOException, SAXException
{
testNillable("wstxtest/msv/nillableDateTime.xml");
}
public void testNillableInt() throws XMLStreamException, IOException, SAXException
{
testNillable("wstxtest/msv/nillableInt.xml");
}
public void testNillableString() throws XMLStreamException, IOException, SAXException
{
testNillable("wstxtest/msv/nillableString.xml");
}

void testNillable(String xmlResource) throws XMLStreamException, IOException, SAXException
{
boolean woodstoxPassed = true;
// Woodstox
final String xsdResource = "wstxtest/msv/nillable.xsd";
{
XMLValidationSchemaFactory schF = XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA);
InputStream schemaInput = getClass().getClassLoader().getResourceAsStream(xsdResource);
InputStream xmlInput = getClass().getClassLoader().getResourceAsStream(xmlResource);
try {
XMLValidationSchema schema = schF.createSchema(schemaInput);
XMLInputFactory2 f = getInputFactory();
setValidating(f, false);

XMLStreamReader2 xmlReader = (XMLStreamReader2) f.createXMLStreamReader(xmlInput);

/* the validation exception is only thrown from the writer
xmlReader.setValidationProblemHandler(new ValidationProblemHandler() {
@Override
public void reportProblem(XMLValidationProblem problem)
throws XMLValidationException {
throw new LocalValidationError(problem);
}
});
xmlReader.validateAgainst(schema);
*/

StringWriter writer = new StringWriter();
XMLStreamWriter2 xmlWriter = (XMLStreamWriter2) getOutputFactory().createXMLStreamWriter(writer);
xmlWriter.setValidationProblemHandler(new ValidationProblemHandler() {
@Override
public void reportProblem(XMLValidationProblem problem)
throws XMLValidationException {
throw new LocalValidationError(problem);
}
});
xmlWriter.validateAgainst(schema);

try {
xmlWriter.copyEventFromReader(xmlReader, false);
while (xmlReader.hasNext()) {
xmlReader.next();
xmlWriter.copyEventFromReader(xmlReader, false);
}
} catch (LocalValidationError e) {
e.printStackTrace();
woodstoxPassed = false;
}
} finally {
if (xmlInput != null) {
xmlInput.close();
}
if (schemaInput != null) {
schemaInput.close();
}
}
}

// javax.xml.validation
boolean javaxXmlValidationPassed = true;
{
InputStream schemaInput = getClass().getClassLoader().getResourceAsStream(xsdResource);
InputStream xmlInput = getClass().getClassLoader().getResourceAsStream(xmlResource);
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
Source schemaFile = new StreamSource(schemaInput);
Schema schema = factory.newSchema(schemaFile);
Validator validator = schema.newValidator();
try {
validator.validate(new StreamSource(xmlInput));
} catch (SAXException e) {
javaxXmlValidationPassed = false;
e.printStackTrace();
} catch (IOException e) {
throw new RuntimeException(e);
}
} finally {
if (xmlInput != null) {
xmlInput.close();
}
if (schemaInput != null) {
schemaInput.close();
}
}
}

if (woodstoxPassed != javaxXmlValidationPassed) {
fail("Woodstox MSV validator " + (woodstoxPassed ? "passed" : "did not pass")
+ " but javax.xml.validation validator "+ (javaxXmlValidationPassed ? "passed" : "did not pass")
+ " for " + xsdResource + " and "+ xmlResource);
}

}

/*
///////////////////////////////////////////////////////////////////////
// Helper classes
///////////////////////////////////////////////////////////////////////
*/

public static class LocalValidationError extends RuntimeException
{
private static final long serialVersionUID = 1L;

protected XMLValidationProblem problem;

LocalValidationError(XMLValidationProblem problem) {
this.problem = problem;
}

public XMLValidationProblem getProblem() {
return problem;
}
}
}
14 changes: 14 additions & 0 deletions src/test/resources/wstxtest/msv/nillable.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://server.hw.demo/nillable"
targetNamespace="http://server.hw.demo/nillable"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:element name="nillableParent">
<xs:complexType>
<xs:sequence>
<xs:element name="nillableDateTime" type="xs:dateTime" nillable="true" minOccurs="0"/>
<xs:element name="nillableInt" type="xs:int" nillable="true" minOccurs="0"/>
<xs:element name="nillableString" type="xs:string" nillable="true" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
3 changes: 3 additions & 0 deletions src/test/resources/wstxtest/msv/nillableDateTime.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<nl:nillableParent xmlns:nl="http://server.hw.demo/nillable">
<nl:nillableDateTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</nl:nillableParent>
3 changes: 3 additions & 0 deletions src/test/resources/wstxtest/msv/nillableInt.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<nl:nillableParent xmlns:nl="http://server.hw.demo/nillable">
<nl:nillableInt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</nl:nillableParent>
3 changes: 3 additions & 0 deletions src/test/resources/wstxtest/msv/nillableString.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<nl:nillableParent xmlns:nl="http://server.hw.demo/nillable">
<nl:nillableString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</nl:nillableParent>

0 comments on commit dbc4b99

Please sign in to comment.