2012-08-12 13 views
6

Attualmente sto usando il mio XSD per convalidare il mio xml. Questa parte funziona bene il mio problema è che voglio ottenere l'elemento del tag/valore che non è valido.Come ottenere l'elemento di un file xml non valido con convalida xsd non riuscita

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

L'idea che avevo, che non è pratico è quello di cercare nel messaggio per la parola "tipo" o "end-tag" e ottenere il valore dopo che, però so che questo non sta per essere buono pratica! Trovo questo frustrante come posso vedere il tag che non è valido ma non riesco a farcela!

Ecco alcuni esempi dell'elemento voglio

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

risposta

12

Qui di seguito è un modo che si potrebbe implementare il vostro caso d'uso utilizzando un ErrorHandler:

MyErrorHandler

Si consiglia di implementare un ErrorHandler che ha mantenuto un riferimento allo XMLStreamReader in modo che, quando si verifica un SAXParseException, è possibile interrogare lo XMLStreamReader per ottenere informazioni sull'elemento. Se si desidera interrompere l'analisi una volta generata un'eccezione, è sufficiente rilanciare lo SAXParseException alla fine di ciascuno dei metodi.

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

si imposta un'istanza ErrorHandler sul 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

Di seguito è riportato uno schema XML di esempio ho usato quando si scrive il codice demo.

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

seguito alcune input di esempio. L'elemento bar ha contenuto non valido.

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

uscita

Di seguito è riportato l'output eseguire il codice demo:

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

È comunque possibile ottenere il valore non valido anche sotto forma di stringa. –

+0

Esattamente quello che volevo – pup784

1

Prova questo si cattura il codice:

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

ottengo solo invalidelement = null? Ho provato anche varie importazioni e sempre nullo – bubblebath

+0

@ user700786 È davvero compito del tuo parser. Per xerces controlla questo: http://xerces.apache.org/xerces2-j/properties.html – execc

Problemi correlati