How to get XML element that violated a multiple field XSD assert

113 views Asked by At

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

0

There are 0 answers