Eine XML-Datei mit Java einzulesen und gegen ein XML-Schema zu validieren ist recht einfach, wenn man weiß wie es geht 😉
Gut, dass es zu diesem Thema einige sehr gute Quellen im Internet gibt (z.B. XML Validation and XPath Evaluation in J2SE 5.0 oder Validation with Java and XML Schema, Part 3). Zuerst habe ich es mit der hier beschriebenen Vorgehensweise probiert: Validating with XML Schema. Kurz gesagt: man holt sich eine DocumentBuilderFactory und konfiguriert sie mittels setValidating(true), um die XML-Datei zu validieren. Dafür muss jedoch in der entsprechenden XML-Datei dann auf das XML-Schema verwiesen werden (mittels schemaLocation), was in meinem Fall zu Problemen beim Auflösen von Pfaden führte (die man aber sicher irgendwie umgehen kann). Darüber hinaus hat die Validierung von Constraints (in meinem Fall unique) nicht korrekt funktioniert, sodass ich den Weg über einen Validator gegangen bin.
Doch zunächst einmal mein Beispiel: Es handelt sich um eine XML-Datei, die (sehr einfach) den Aufbau einer Fertigungsanlage beschreibt (siehe Bild hier: Wegfindung mit dem A*-Algorithmus in Java). Eine ProductionPlant enthält Modules (die Teile der Anlage wie z.B. Förderbänder und Drehteller) und Connections zwischen diesen, die jedoch für mein Beispiel nicht wichtig sind. Jedes Module hat eine (eindeutige → unique) ID.
Der eigentliche Code, der nun die XML-Datei einliest und validiert, ist der folgende:
// create a factory that understands namespaces and validates the XML input
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
// read the XML file
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("SamplePlant.xml"));
// create a SchemaFactory and a Schema
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source schemaFile = new StreamSource(new File("ProductionPlant.xsd"));
Schema schema = schemaFactory.newSchema(schemaFile);
// create a Validator object and validate the XML file
Validator validator = schema.newValidator();
validator.validate(new DOMSource(doc));
System.out.println("XML file successfully validated.");
Download
In eine Klasse gepackt und um die import-Anweisungen und einen (einfachen) ErrorHandler ergänzt, gibt es das Ganze hier zum Download: PlantBuilder.
Wie folgt kann das kleine Programm gestartet werden:
Hallo,
ich habe diesen Code benutzt um eine XML-Datei gegen ein selbstgeschriebenes Schema zu validieren. Nachdem ich zuerst Fehlermeldungen bekam, da das Schema wohl noch nicht so 100%ig korrekt war, hat er mir immer ausgegeben, dass das XML file successfully validated sein soll. Nur, es wird anscheinend jede XML-datei succssfully validated… Also ich konnte auch Fehler einbauen und habe danach auch noch andere XML-files ausprobiert und es kommt immer die Erfolgsmeldung.
Woran kann das liegen?
Danke für eine Antwort. Ich bin da so n bisschen an meinen Grenzen.
Gruß,
Daniel
@Daniel: Sorry, kann ich dir so nicht sagen! Schickst du mir mal dein Programm und die XML-/XSD-Datei per Mail?
Danke für den Code.
Leider funktioniert das mit JRE6 nicht wie gewünscht. Der DocumentBuilder validiert, wenn er ein Schema finden kann, die Datei schon selbst. Falls dann eine Schema-Inkonformität gefunden wird, schmeisst schon der DocumentBuilder eine (ungenaue) Fehlermeldung. Da nützt auch nichts, wenn man bei der DocumentBuilderFactory.setValiditing(false) setzt, denn das bezieht sich auf DTDs, nicht auf XSD Schemas…
Mit folgendem Code geht es:
Den Error Handler kann man so belassen wie von dir angegeben.