I have an XSD <assert>
rule that validates multiple fields, for examle:
<xs:assert test="if(FIELD1/@value = (2,3,4) and not(exists(FIELD2/@value))) then false() else true()" xerces:message="Field 1 is 2, 3 or 4 but field 2 still has no value. Check that, please">
<xs:annotation>
<xs:appinfo>
<das:rule_fields>
<das:field value="FIELD1"/>
<das:field value="FIELD2"/>
</das:rule_fields>
</xs:appinfo>
</xs:annotation>
</xs:assert>
My XML that is validated looks like this:
<body>
<residents>
<resident>
<data>
<ID value="123">
<FIELD1 value="3"/>
<FIELD2/>
</data>
</resident>
<resident>
<data>
<ID value="456">
<FIELD1 value="0"/>
<FIELD2/>
</data>
</resident>
<resident>
<data>
<ID value="789">
<FIELD1 value="3"/>
<FIELD2 value="1"/>
</data>
</resident>
</residents>
</body>
My validation code looks like this (made a lot shorter and easier):
try {
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");
XMLStreamReader reader = XMLInputFactory.newFactory().createXMLStreamReader(XML);
Schema schema = factory.newSchema(new Source[] {
new StreamSource(new File(MY_XSD))
});
Validator validator = schema.newValidator();
validator.setErrorHandler(new ErrorHandler(){
@Override
public void warning(SAXParseException exception) throws SAXException {
exceptionBase.add(exception);
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
exceptionBase.add(exception);
}
@Override
public void error(SAXParseException exception) throws SAXException {
exceptionBase.add(exception);
}
});
validator.validate(new StAXSource(reader));
} catch (IOException | SAXException | XMLStreamException | FactoryConfigurationError e) {
e.printStackTrace();
}
When I validate the XML, the resident/data
block with ID
123 violates the assert, because FIELD1 is 3 (in 2,3,4) and FIELD2 has no value. My SAXParseException is thrown with the message of my assert ("Field 1 is 2, 3 or 4 but field 2 still has no value. Check that, please"). The XMLStreamReader reader
stands at the position of my closing </data>
tag which is an END_ELEMENT. For an END_ELEMENT, i cannot call reader.getElementText()
so is there a chance to get back to the start element and print the content of <ID>
(123)?
Or is there any other way to get the whole <data>---</data>
block that caused the error?
Kind regards Timo