JAXB: XSD Versionieren?

Hallo zusammen,

hab die Tage etwas mit JAXB und XSDs gespielt. Tolle Sache.

Eine Frage stellt sich mir aber:

Wenn ich mir jetzt ein XML Schema überlege, dies in einer XSD definiere, dann kann ich mir daraus ja Java-Klassen generieren lassen.

Was aber wenn sich das XML Schema soweit ändert (neue Version), dass die resultierenden Java-Klassen nicht mehr kompatibel sind?

Man könnte jetzt argumentieren dass das ja nicht tragisch ist. Aber wenn mein Programm Daten aus einer “alten” XML lesen und in das neue XML überführen/konvertieren muss (was vllt. wegen des Inhalts nur programmatisch geht), dann muss ich beide XML-Java-Objektstrukuren laden können. Mit einem Classloader würde ich hier nicht unbedingt hantieren wollen.

Der Package-Name der generierten Klassen wird ja aus dem Namespace heraus erzeugt.

Bis dato würde der Namespace z.B. so aussehen:

http://meinedomain.de/xsd/MeinXML

was das Package

de.meinedomain.xsd.meinxml 

generieren würde.

Was ist denn hier best-practice? Einfach im Namespace ein Versionselement definieren?

http://meinedomain.de/xsd/MeinXML/v0 --> de.meinedomain.xsd.meinxml.v0 ???

Damit könnte ich problemlos beide Varianten als Java-Klassen laden und durch den anderen Packagenamen voneinander unterscheiden.

Allerdings habe ich gelesen, dass man sowas nicht in den Namespace packen sollte. Wieso hab ich aber nicht rausgefunden.

Any ideas?

  • Alex

*** Edit ***

Aktuell erscheint mir meine Lösung am praktikabelsten. Wüsste jetzt nicht wieso ich im Namespace keine “Version” einbauen darf/sollte. Der Namespace ändert sich ja nicht einfach so. Und wenn, dann ist das im Endeffekt ja dann ein anderer Namespace der etwas ganz anderes beinhalten (kann, und bei mir auch) wird.

Hab mal testweise in andere XML Projekte geschaut. Da wird das zum Teil auch so gemacht.

Das Problem besteht in der oder ähnlicher Form auch in anderen Bereichen.

Angenommen du hast eine Datenbank und in Java das entsprechende Gegenstück.

Erweitert/Ändert man das Datenmodel, dann kann man eventuell Probleme bekommen, wenn man
• auf einem alten DB-Dump arbeiten möchte
• remote mit neuen Clients auf ältere Kunden-DBs zugreifen möchte zum Debuggen

Was dann damals bei der einen Firma gemacht wurde ist zu schauen, in welcher Version die DB ist und dann die nötigen Querys ausführen so dass die DB danach im neusten Zustand ist. Danach alle Clients auf die neuste Version hiefen oder Rollback bei Problemen.

Auf XML und JaxB übertragen, könnte dies bedeuten das XML erst zu prüfen, dann zum Beispiel via XSLT die Kompatibilität herstellen und dann das daraus resultierende Dokument zu verarbeiten.

Ich stelle mir das ganze eben schwierig vor, wenn die Anzahl der Versionen steigt und es dann eben nicht nur zwei Versionen gibt, sondern Dutzende. Dazu der Code, um von jeder Version zum Nachfolger zu kommen, sowie die Änderungen um mit der jeweils aktuellen Version dann auch zu arbeiten.

Mit XSLT muss ein Dokument eben x Transformationen durchlaufen um ebensoviele Versionen aufzuholen.

Nachteil ist, dass man eben etwas limitiert ist.

Also ich löse das immer mit einem “version”-Attribut am Root-Element:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://sample.domain.com/sample/xsd"
	xmlns:pf="http://sample.domain.com/sample/xsd"
	elementFormDefault="qualified">
	<element name="MyRoot">
		<complexType>
			<sequence>
			  <!-- content here -->
			</sequence>
			<attribute name="version" type="string" use="required" fixed="1.0.167" >
			<!-- more root element attributes -->
		</complexType>
	</element>

dann kann man den Unmarshaller auf “validate” stellen und der beschwert sich dann, wenn die Version nicht stimmt.

Oder man selektiert aufgrund dieser Version den zu verwendenden Programmteil, der damit umgehen kann…

Wenn man noch etwas mit maven experimentiert kann man sicher auch vor dem Generieren der Mapper-Klassen noch die Versionsnummer mit der aus der POM abgleichen…

bye
TT