如何使用失败的xsdvalidation获取xml文件的元素和无效的xml文件

我目前正在使用我的XSD来validation我的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 "". 

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

MyErrorHandler

我建议实现一个ErrorHandler来维护对XMLStreamReader的引用,这样当发生SAXParseException时,您可以询问XMLStreamReader以获取有关该元素的信息。 如果您希望在抛出exception后停止解析,只需在每个方法的末尾重新抛出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); } } 

演示

您在Validator上设置了ErrorHandler的实例。

 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架构。

            

input.xml中

以下是一些示例输入。 bar元素包含无效内容。

   valid invalid  

产量

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

 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) 

在你捕获代码中尝试这个:

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