Mai 08

XSD aus XML mit mehreren Namespaces generieren

Tag: Tipps und TricksTorsten @ 23:04

Manchmal kommt es vor, dass man mit XML-Import-Daten konfrontiert wird, die kein dazugehöriges XSD bieten (und auf deren Struktur man leider auch keinen Einfluss hat, und man sie so verarbeiten muss, wie sie sind). Nun gibt es verschiedene Möglichkeiten, sich aus XML ein XSD generieren zu lassen.

Visual Studio bietet im Command Prompt über XSD.exe eine solche Möglichkeit, z.B. via
xsd.exe A.xml /outputdir:d:\outputs

Es generiert daraufhin eine XSD pro Namespace (leider mit unschönen Dateinamen wie A_app1, A_app2). Die XSDs sehen als solches schon nicht schlecht aus, allerdings kommt xsd.exe scheinbar noch nicht so richtig mit einigen Spezialfällen bei multiplen Namespaces zurecht, wie z.B. in diesem vereinfachten XML:

<?xml version="1.0" encoding="UTF-8"?>
<A>
    <A:B>
        <B:B Key="B123">
          <B:Attribute1>test</B:Attribute1>
          <B:Attribute2>test</B:Attribute2>
        </B:B>
        <B:B Key="B234">
          <B:Attribute1>test</B:Attribute1>
          <B:Attribute2>test</B:Attribute2>
        </B:B>
    </A:B>
</A>

Als Resultat kam dann beim Validieren des XML gegen die generierten XSDs immer folgende Fehlermeldung: The element ‚B‘ in namespace ‚A‘ has invalid child element ‚B‘ in namespace ‚B‘.

Was beim xsd.exe Tool auch recht unschön ist, dass es die Datentypen nicht intern bereits analysiert und im XSD setzt. Also z.B. xs:integer anstatt überall xs:string.

Ich habe daraufhin etwas recherchiert und das Tool Trang gefunden: Trang
Trang ist ein Multi-format schema converter auf Basis RELAX NG.

Auszug aus dem Manual:

Trang takes as input a schema written in any of the following formats:

  • RELAX NG (XML syntax)
  • RELAX NG (compact syntax)
  • XML 1.0 DTD

and produces as output a schema written in any of the following formats:

  • RELAX NG (XML syntax)
  • RELAX NG (compact syntax)
  • XML 1.0 DTD
  • W3C XML Schema

Über folgenden Aufruf generiert Tran dann ebenfalls XSDs aus einem XML:
java -jar trang.jar -I xml -O xsd A.xml A.xsd

Es hat daraufhin gültige XSDs passend zu den Namespaces aus meinem Bsp-XML generiert, so dass ich dieses fehlerfrei validieren konnte. Sogar in sinnvolle Dateinamen, also in dem Bsp. A.xsd, B.xsd.

Ebenfalls hat es bereits intern auf Grundlage der (vorhandenen) XML-Daten die Datentypen analysiert und z.B. Typen wie type=“xs:NMTOKEN“, type=“xs:boolean“, etc. gesetzt.

Bei Feldern, die nicht gefüllt waren, also z.B. <attribute1></attribute1> hat es den Datentyp complex angenommen (so dass man dies ggf. manuell im XSD nachbessern muss).

Alles in Allem bin ich recht zufrieden mit Trang, es nimmt einem einiges an Arbeit ab, die man bei diversen anderen Tools manuell nachziehen müsste.

Natürlich sind solche Tools nie als „Starten und 1:1 Output verwenden“ gedacht. Man muss die generierten Inhalte immer detailliert durchgehen und Details nachziehen (wie z.B. auch Kardinalitäten minOccurs, maxOccurs, die solche Tools natürlich nicht erraten können). Und auch ggf. die Datentypen noch verfeinern. Aber man hat dann bereits eine gute Grundlage auf der man aufsetzen kann.

Es gibt natürlich auch noch diverse andere Tools, u.a. auch Online-Generatoren.
Eine Übersicht findet man hier.

Um die XML-Daten im Code weiterzuverarbeiten braucht man anschließend Klassen, die die XML-Attribute repräsentieren. Auch hier gibt es mehrere Möglichkeiten, siehe Blog-Eintrag Generieren von .NET Klassen aus XSDs bzw. XML mit mehreren Namespaces.