2012-08-12 4 views
6

Obecnie używam mojego XSD do sprawdzania poprawności mojego xml. Ta część działa dobrze mój porblem jest to, że chcę uzyskać element tag/value, który jest nieprawidłowy.Jak uzyskać element i nieprawidłowy plik xml z nieudaną walidacją xsd

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

Pomysł miałem co nie jest praktyczne jest, aby spojrzeć w komunikacie dla słowa „rodzaj” lub „end-tag” i uzyskać wartość po nim, jednak wiem, że to nie będzie dobry ćwiczyć! To frustrujące, ponieważ widzę tag, który jest nieważny, ale nie mogę go zdobyć!

Oto kilka przykładów elementu Chcę

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

Odpowiedz

12

Poniżej znajduje się sposób, że można realizować swój przypadek użycia za pomocą ErrorHandler:

MyErrorHandler

Polecam implementację ErrorHandler, która zachowała odniesienie do XMLStreamReader, więc gdy pojawi się SAXParseException, możesz przesłuchać XMLStreamReader, aby uzyskać informacje o elemencie. Jeśli chcesz, aby parsowanie zatrzymało się po wyrzuceniu wyjątku, po prostu przepisz SAXParseException na końcu każdej z metod.

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

ustawić instancję ErrorHandler na 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

Poniżej znajduje się przykładowy schemat XML Kiedyś podczas pisania kodu 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

Poniżej znajdują się wejścia próbki. Element bar zawiera nieprawidłową treść.

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

Wyjście

Poniżej jest wyjście z uruchomieniem kodu 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

Czy mimo to mogę uzyskać niepoprawną wartość również w postaci ciągu znaków. –

+0

Dokładnie to, co chciałem – pup784

1

Spróbuj to w wy kod haczyk:

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

ja po prostu invalidelement = null? Próbowałem również różnych importów i zawsze null – bubblebath

+0

@ user700786 To naprawdę zależy od wdrożenia parsera. W przypadku xercji sprawdź: http://xerces.apache.org/xerces2-j/properties.html – execc

Powiązane problemy