2012-08-12 14 views
6

Actualmente estoy usando mi XSD para validar mi xml. Esta parte funciona bien, mi problema es que quiero obtener el elemento de la etiqueta/valor que no es válido.Cómo obtener el elemento y el archivo xml no válido con xsd Validación fallida

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

La idea que tenía, que no es práctico es buscar en el mensaje de la palabra "tipo" o "etiqueta final" y obtener el valor después de que, sin embargo sé que esto no va a ser bueno ¡práctica! Esto me resulta frustrante, ya que puedo ver la etiqueta que no es válida pero no puedo obtenerla.

Éstos son algunos ejemplos del elemento Quiero

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

Respuesta

12

A continuación se muestra una manera que se podría poner en práctica su caso de uso utilizando un ErrorHandler:

MyErrorHandler

Recomendaría implementar un ErrorHandler que mantenga una referencia al XMLStreamReader para que cuando ocurra un SAXParseException pueda interrogar al XMLStreamReader para obtener información sobre el elemento. Si desea que el análisis se detenga una vez que se lanza una excepción, simplemente vuelva a lanzar el SAXParseException al final de cada uno de los métodos.

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

} 

demostración

configura una instancia de ErrorHandler en el 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

A continuación se muestra un esquema XML de ejemplo que se utiliza al escribir el código de demostración.

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

A continuación se muestra una cierta entrada. El elemento bar tiene contenido no válido.

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

salida

A continuación se muestra el resultado de la ejecución del código de demostración:

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

¿Hay alguna forma en que pueda obtener el valor no válido también en forma de cadena? –

+0

Exactamente lo que quería – pup784

1

probar este en que captura código:

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

apenas consigo invalidelement = null? He intentado varias importaciones y siempre nulo – bubblebath

+0

@ user700786 Depende realmente de la implementación del analizador. Para xerces comprueba esto: http://xerces.apache.org/xerces2-j/properties.html – execc

Cuestiones relacionadas