小编典典

如何通过失败的xsd验证获取元素和无效的xml文件

java

我当前正在使用XSD验证xml。这部分工作正常,我的问题是我想获取无效的标记/值的元素。

    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(xml));
    XMLStreamReader reader = null;
    SchemaFactory factory=SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = factory.newSchema(xsdschemalocation);
    Validator validator = schema.newValidator(); 
    try
    {
        reader = XMLInputFactory.newInstance().createXMLStreamReader(new StreamSource(new StringReader(xml)));
    } catch (XMLStreamException ex)
    {
        LogController.getLogger().logSEVERE("Unable to create the streamreader from the xml source", ex.getLocalizedMessage());
        return false;
    }
    try
    {
        validator.validate(new StAXSource(reader));
    }
    catch (IOException ex)
    {
        LogController.getLogger().logSEVERE("IOException in the validatation has been caused as the reader has become null", ex.getLocalizedMessage());
        return false;
    }
catch(SAXException saxe)
    {
        LogController.getLogger().logWARNING("Their is a validation error with the xml", saxe.getLocalizedMessage());
        //*****HERE I WANT THE TAG THAT HAS THE ERROR
        ClientCommunication.ErrorMessageForClient(VALIDATION_ERROR, socket);
        CloseClientConnection();
        return;
    }

我有一个不切实际的想法,就是在消息中查找“ type”或“ end-
tag”一词,并在其后获取值,但是我知道这不是一个好习惯!我发现这很令人沮丧,因为我看到了无效但无法抓住的标签!

这是我想要的元素的一些示例

1. Message: Element type "first" must be followed by either attribute specifications, ">" or "/>".

2. javax.xml.stream.XMLStreamException: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 353; cvc-pattern-valid: Value '079e989989' is not facet-valid with respect to pattern '([0-9])+' for type 'phoneNumber'.

3. Message: The element type "firstLine" must be terminated by the matching end-tag "</firstLine>".

阅读 215

收藏
2020-11-13

共1个答案

小编典典

下面是一种使用来实现用例的方法ErrorHandler

MyErrorHandler

我建议您实施一个ErrorHandler,以维护对的引用,XMLStreamReader以便在SAXParseException发生时可以查询XMLStreamReader来获取有关该元素的信息。如果要在引发异常后停止分析,只需SAXParseException在每个方法的末尾重新抛出。

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);
    }

}

演示版

您可以设置的一个实例ErrorHandlerValidator

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

以下是编写演示代码时使用的示例XML模式。

<?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

以下是一些示例输入。该bar元素具有无效的内容。

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

输出量

以下是运行演示代码的输出:

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)
2020-11-13