How to get the element of and invalid xml file with failed xsd Validation

后端 未结 2 543
庸人自扰
庸人自扰 2020-12-28 23:34

I am currently using my XSD to Validate my xml. This part works fine my porblem is that I want to obtain the element of the tag /value that is invalid.

    I         


        
相关标签:
2条回答
  • 2020-12-28 23:43

    Below is a way that you could implement your use case using an ErrorHandler:

    MyErrorHandler

    I would recommend implementing an ErrorHandler that maintained a reference to the XMLStreamReader so that when a SAXParseException occurs you could interrogate the XMLStreamReader to get information about the element. If you want the parsing to stop once an exception is thrown simply rethrow the SAXParseException at the end of each of the methods.

    package forum11921190;
    
    import javax.xml.stream.XMLStreamReader;
    import org.xml.sax.*;
    
    public class MyErrorHandler implements ErrorHandler {
    
        private XMLStreamReader reader;
    
        public MyErrorHandler(XMLStreamReader reader) {
            this.reader = reader;
        }
    
        @Override
        public void error(SAXParseException e) throws SAXException {
            warning(e);
        }
    
        @Override
        public void fatalError(SAXParseException e) throws SAXException {
            warning(e);
        }
    
        @Override
        public void warning(SAXParseException e) throws SAXException {
            System.out.println(reader.getLocalName());
            System.out.println(reader.getNamespaceURI());
            e.printStackTrace(System.out);
        }
    
    }
    

    Demo

    You set an instance of ErrorHandler on the Validator.

    package forum11921190;
    
    import javax.xml.XMLConstants;
    import javax.xml.stream.*;
    import javax.xml.transform.stax.StAXSource;
    import javax.xml.transform.stream.StreamSource;
    import javax.xml.validation.*;
    
    public class Demo {
    
        private static final StreamSource XSD = new StreamSource("src/forum11921190/schema.xsd");
        private static final StreamSource XML = new StreamSource("src/forum11921190/input.xml");
    
        public static void main(String[] args) throws Exception {
            SchemaFactory factory=SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            Schema schema = factory.newSchema(XSD);
    
            XMLStreamReader reader = XMLInputFactory.newFactory().createXMLStreamReader(XML);
    
            Validator validator = schema.newValidator();
            validator.setErrorHandler(new MyErrorHandler(reader));
            validator.validate(new StAXSource(reader));
    
        }
    
    }
    

    schema.xsd

    Below is a sample XML schema I used when writing the demo code.

    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://www.example.com"
        xmlns:tns="http://www.example.com"
        elementFormDefault="qualified">
        <element name="root">
            <complexType>
                <sequence>
                    <element name="foo" type="string"/>
                    <element name="bar" type="int"/>
                </sequence>
            </complexType>
        </element>
    </schema>
    

    input.xml

    Below is some sample input. The bar element has invalid content.

    <?xml version="1.0" encoding="UTF-8"?>
    <root xmlns="http://www.example.com">
        <foo>valid</foo>
        <bar>invalid</bar>
    </root>
    

    Output

    Below is the output from running the demo code:

    bar
    http://www.example.com
    org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'invalid' is not a valid value for 'integer'.
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:384)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:318)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:423)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3188)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(XMLSchemaValidator.java:3103)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(XMLSchemaValidator.java:3013)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(XMLSchemaValidator.java:2156)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(XMLSchemaValidator.java:824)
        at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.endElement(ValidatorHandlerImpl.java:565)
        at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:261)
        at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.handleEndElement(StAXStream2SAX.java:295)
        at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.bridge(StAXStream2SAX.java:167)
        at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.parse(StAXStream2SAX.java:120)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:674)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:723)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:336)
        at com.sun.org.apache.xerces.internal.jaxp.validation.StAXValidatorHelper.validate(StAXValidatorHelper.java:94)
        at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:118)
        at javax.xml.validation.Validator.validate(Validator.java:127)
        at forum11921190.Demo.main(Demo.java:26)
    bar
    http://www.example.com
    org.xml.sax.SAXParseException: cvc-type.3.1.3: The value 'invalid' of element 'bar' is not valid.
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:384)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:318)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:423)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3188)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(XMLSchemaValidator.java:3104)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(XMLSchemaValidator.java:3013)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(XMLSchemaValidator.java:2156)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(XMLSchemaValidator.java:824)
        at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.endElement(ValidatorHandlerImpl.java:565)
        at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:261)
        at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.handleEndElement(StAXStream2SAX.java:295)
        at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.bridge(StAXStream2SAX.java:167)
        at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.parse(StAXStream2SAX.java:120)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:674)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:723)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:336)
        at com.sun.org.apache.xerces.internal.jaxp.validation.StAXValidatorHelper.validate(StAXValidatorHelper.java:94)
        at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:118)
        at javax.xml.validation.Validator.validate(Validator.java:127)
        at forum11921190.Demo.main(Demo.java:26)
    
    0 讨论(0)
  • 2020-12-28 23:51

    Try this in you catch code:

    catch(SAXException saxe) {
        Element invalidElement = (Element) validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");
        System.out.println("Error: " + saxe.getMessage());
        System.out.println("Invalid element: " + invalidElement);
    }
    
    0 讨论(0)
提交回复
热议问题