XML Validierung ?

HuberDe

Mitglied
Hallo zusammen,

ich benutze Java6 und habe versucht eine ganz simple Validierung eines XML Dokuments umzusetzen, stoße jedoch auf eine Wand! Ich habe den Code aus der JAPI genommen, welcher hier zu finden ist: KLICK

In etwa das Gleiche ist hier auch nochmal zu finden. Sogar mit Beispiel XML und Schemadokument.

Ich verwende den folgenden Code:

Code:
// Create a SchemaFactory capable of understanding WXS schemas.
            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

            // Load a WXS schema, represented by a Schema instance.
            Schema schema = factory.newSchema(schemaFile);

            // Create a Validator object, which can be used to validate
            // an instance document.
            Validator validator = schema.newValidator();

            // Validate the DOM tree.
            validator.validate(new DOMSource(document));

Mein Problem ist jetzt, dass die Validierung schiefgeht. Ich bekomme eine SAXParseException:

Code:
 org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'birthdate'.

Ich habe viel im Internet gesucht, konnte jedoch keine Lösung finden, da ich scheinbar der Einzige bin, der dieses Problem hat.

Ich hoffe es kann mir jemand weiterhelfen.
Danke
 
Hallo,

könntest du mal bitte die XML-Datei und das Schema posten?

Es sieht für mich nämlich so aus, dass er in der XML-Datei ein Element findet, welches im Schema nicht definiert ist.

MFG

zEriX
 
Die hab ich auch aus dem 2. Link genommen, da ich mit meinen die Probleme hatte. Aber mit denen vom Link siehts genau gleich aus:

XML:
Code:
<?xml version="1.0"?>
   
<birthdate>
    <month>January</month>
    <day>21</day>
    <year>1983</year>
</birthdate>

Schema:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
  <xs:element name="birthdate">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="month" type="xs:string"/>
        <xs:element name="day" type="xs:int"/>
        <xs:element name="year" type="xs:int"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
 
Hallo,

schau mal hier:
Java:
/**
 * 
 */
package de.tutorials;

import java.io.StringReader;

import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

/**
 * @author Thomas.Darimont
 * 
 */
public class XmlSchemaValidationExample {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {

        String schema = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
                + "<xs:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"http://www.w3.org/2001/xml.xsd\"/>"
                + "<xs:element name=\"birthdate\">" + "<xs:complexType>"
                + "<xs:sequence>"
                + "<xs:element name=\"month\" type=\"xs:string\"/>"
                + "<xs:element name=\"day\" type=\"xs:int\"/>" +
                "<xs:element name=\"year\">" + "<xs:simpleType>"
                + "<xs:restriction base=\"xs:int\">" +
                "<xs:minInclusive value=\"1950\"></xs:minInclusive>"
                + "<xs:maxInclusive value=\"2400\"></xs:maxInclusive>"
                + "</xs:restriction>" + "</xs:simpleType>" + "</xs:element>"
                + "</xs:sequence>" + "</xs:complexType>" + "</xs:element>"
                + "</xs:schema>";

        String validXml = "<?xml version=\"1.0\"?>" + "<birthdate>"
                + "<month>January</month>" + "<day>21</day>"
                + "<year>1983</year>" + "</birthdate>";

        String invalidXml = "<?xml version=\"1.0\"?>" + "<birthdate>"
                + "<month>January</month>" + "<day>21</day>"
                + "<year>3000</year>" + "</birthdate>";

        Validator validator = SchemaFactory.newInstance(
                XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(
                new StreamSource(new StringReader(schema))).newValidator();

        validator.validate(new StreamSource(new StringReader(validXml)));
        System.out.println("#####");
        validator.validate(new StreamSource(new StringReader(invalidXml)));

    }

}

Ausgabe:
Code:
#####
Exception in thread "main" org.xml.sax.SAXParseException: cvc-maxInclusive-valid: Value '3000' is not facet-valid with respect to maxInclusive '2400' for type '#AnonType_yearbirthdate'.
    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:410)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3165)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(XMLSchemaValidator.java:3068)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(XMLSchemaValidator.java:2978)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(XMLSchemaValidator.java:2121)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(XMLSchemaValidator.java:791)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1772)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2923)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:645)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:508)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
    at com.sun.org.apache.xerces.internal.jaxp.validation.StreamValidatorHelper.validate(StreamValidatorHelper.java:144)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:107)
    at javax.xml.validation.Validator.validate(Validator.java:127)
    at de.tutorials.XmlSchemaValidationExample.main(XmlSchemaValidationExample.java:53)

Gruß Tom
 
Hi Tom,

danke Dir für die Antwort. Dein Code funktioniert soweit. Ich konnte es jetzt soweit abstahieren, dass ich rausgefunden habe, dass mein Code im Bereich

Code:
validator.validate(new DOMSource(document));

Probleme macht. Wenn ich deinen xml Datei als String an den Validator gebe funktioniert der Rest meiner Methode auch. Nur als DOMSource Objekt kann ich scheinbar nicht übergeben. Ich bin noch am Anaysieren, vlt. hat ja aber jemand noch nen Tip.

Das Dokument lese ich mit fogendem Code ein:

Code:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try
{
  DocumentBuilder builder = factory.newDocumentBuilder();
  Document myDocument = builder.parse(new File("C:\\datei.xml"));
  ...

Gruß, Denis
 
Zuletzt bearbeitet:
Hallo,

ich habe versucht anhand des oben stehenden Beispiels eine Validierung durchzuführen und scheitere wohl im moment an den Namespaces.
Es hat zwar funktioniert der SchemaFactory meinen Namespace mitzugeben, allerdings scheitere ich im Moment daran, dass mein Schema ein weiteres Schema includiert. Die beiden Schemata liegt zwar im selben Namespace, aber trotzdem scheint es beim includierten Probleme zu geben. Jetzt hab ich keine Idee wie ich den Namespace des inludierten bekannt machen könnte.

bin für jeden Tipp dankbar

Gruß Philipp
 
Die Lösung ist recht einfach. Liest man die Dateien (Schema und XML-Datei) über ein StreamSource Objekt ein, funktioniert alles einwandfrei.

Gruß, Denis
 
hallo

habe das beispiel auch mal implementiert und siehe da es geht... habe es auch mit externen dateien hinbekommen.
habe mir mal zum test ne xml und passende xsd gebaut, wo default werte enthalten sind, also die xml ja irgendwie automatisch gefüllt werden muss.

nun habe ich das problem den bogen zu finden wie ich einen validierten DOM mit default werten erstelle...

hat einer ne ahnung
 
Zurück