2012-08-12 48 views
6

我目前使用我的XSD來驗證我的xml。這部分工作正常我的porblem是我想獲得無效的標記/值的元素。如何獲取失敗的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; 
    } 

我的想法是不實際的是看單詞「類型」或「結束標記」的消息,並獲得價值後,但我知道這不會是好實踐!我發現這令人沮喪,因爲我可以看到無效但無法控制的標籤!

以下是該元素的一些例子我想

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>". 

回答

12

以下是你可以用一個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); 
    } 

} 

演示

您在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架構。

<?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) 
+0

是否有無論如何,我可以以字符串的形式獲取無效值。 – 2016-02-02 21:49:18

+0

正是我想要的 – pup784 2016-06-01 18:19:14

1

試試這個在你趕上代碼:

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

我只是得到invalidelement = NULL?我也嘗試過各種導入,並始終爲空 – bubblebath 2012-08-12 10:39:02

+0

@ user700786這真的取決於您的解析器實現。對於xerces檢查:http://xerces.apache.org/xerces2-j/properties.html – execc 2012-08-13 19:43:51

相關問題