Wie kann ich überprüfen, ob ein XSD-Schema eine Teilmenge eines anderen XSD-Schemas ist?
Wir erstellen eine System-of-Systems-Anwendung, die eine Sammlung von "Blueprint" -XSD-Schemas verwendet (die alle möglichen Eingaben oder Ausgaben definieren, die für eine Unterkomponente verfügbar sind). Viele Unterkomponenten werden implementiert, und diese Unterkomponenten übergeben Daten unter Verwendung von XML-Dateien untereinander. Jede Unterkomponente erstellt eine Teilmenge des relevanten Blueprint-XSD-Schemas (um anzugeben, welche der möglichen Eingaben oder Ausgaben für die Implementierung ausgewählt wurde). Jede XML-Datendatei, die mit einem XSD-Subset-Schema validiert, muss auch mit dem Blueprint-XSD-Schema validiert werden, das Gegenteil ist jedoch nicht wahr (da das XSD-Subset-Schema möglicherweise nicht alle optionalen oder optionalen XML-Elemente aus dem Blueprint-XSD-Schema enthält) und es kann gewählt werden, erlaubte Datenwerte auf einem vorhandenen XML-Tag weiter einzuschränken). Das System überprüft alle XML-Eingaben für eine Unterkomponente anhand des Untergruppen-XSD-Schemas (um fehlerhafte Eingaben zu kennzeichnen und die Quelle datenbezogener Probleme zu isolieren).
Während des Testens möchten wir überprüfen, dass das XSD-Schema jeder Unterkomponente wirklich ein Teil des zugehörigen XSD-Schemas ist, aber wir haben keine automatische Möglichkeit, diese Überprüfung durchzuführen. Diese XSD-Schemas sind ziemlich groß und hässlich, um diese Tests von Hand durchzuführen. Es wäre schön, eine Art "validiere XSD-Datei 1 gegen XSD-Datei 2" zu haben, ähnlich wie Java eine Validierung einer XML-Datei gegen ein XSD-Schema durchführen kann. Wir möchten bestätigen, dass das Subset-XSD-Schema jeder Unterkomponente keine Kombinationen von XML-Ein- / Ausgaben zulässt, die gegen das XSD-Schema des Blueprints verstoßen würden. Mit dieser Schema-zu-Schema-Fähigkeit wäre es auch sehr hilfreich zu überprüfen, ob die Ausgabe-XML von Unterkomponente A geeignet wäre, als Eingabe für Unterkomponente B verwendet zu werden (wir können leicht eine einzelne Ausgabe-XML gegen ein XSD-Schema validieren, aber Wir möchten bestätigen, dass alle möglichen XML-Ausgaben von Unterkomponente A gegen das XSD-Schema von Unterkomponente B validiert werden.
Hilfreiche Informationen: Diese Anwendung ist eine Sammlung von Java 6-Anwendungen, die als OSGi-Bundles implementiert und mit Maven 2.2.1 kompiliert / ausgeführt werden. Es gibt keine Anforderungen für die Verwendung einer bestimmten Entwicklungs-IDE. Das System wird in einer Microsoft Windows XP-Umgebung getestet, aber es ist geplant, dieses System auch in anderen Umgebungen auszuführen (daher wäre eine plattformübergreifende Lösung vorzuziehen).
Die einfachste Möglichkeit, die gewünschte Beziehung sicherzustellen, besteht darin, die Typen der Teilmengenschemas durch Einschränkung aus den Typen des Blueprint-Schemas abzuleiten. Es hört sich so an, als wäre das Boot bereits gesegelt.
Wie andere hier auch, sind mir keine Werkzeuge bekannt, die das sofort machen (obwohl, wenn Petru Gardea sagt, dass QT Assistant es kann, lohnt es sich, nachzufolgen).
Eine Komplikation besteht darin, dass es zwei verschiedene Möglichkeiten gibt, die zu überprüfende Teilmengen- / Obermengenrelation anzuzeigen: (1) Jedes Dokument (oder Element), das als gültig von Schema 1 akzeptiert wird, wird auch von Schema 2 als gültig akzeptiert (ohne Bezug) (2) die typisierten Dokumente, die durch Validierung erzeugt werden (in dem die Spezifikation das Post-Schema-Validierungs-Infoset aufruft) gegenüber den Schemas 1 und 2 stehen in einer geeigneten Beziehung zueinander: wenn ein Element oder Attribut ist in Baum 1 gültig und in Baum 2 gültig; der ihm in Baum 1 zugewiesene Typ ist eine Beschränkung des Typs, der ihm in Baum 2 zugewiesen ist; usw. Wenn die Schemata 1 und 2 unabhängig voneinander entwickelt wurden, sind die Chancen, dass ihre Typen durch Ableitung verwandt sind, schlecht, also denke ich, dass Sie die erste Annäherung an die Frage im Sinn haben.
Das Problem ist jedoch definitiv entscheidbar, in jeder Form. Für jedes Schema (ich verwende den Begriff sorgfältig) gibt es per Definition eine endliche Anzahl von Typen und eine endliche Anzahl von Elementnamen, die deklariert werden; Daraus folgt, dass es eine endliche Anzahl (möglicherweise groß) von Paaren aus Elementnamen und -typen gibt.
Der Algorithmus kann so etwas gehen.
Beginnen Sie mit dem erwarteten Wurzelelement. (Wenn mehrere mögliche Wurzelelemente vorhanden sind, müssen Sie diese im allgemeinen Fall für jeden von ihnen ausführen.) Wenn das erwartete Wurzelelement E ist, mit dem Typ T1 in Schema 1 und T2 in Schema 2, dann Stellen Sie die Aufgabe "Vergleiche T1 und T2" in eine Warteschlange mit offenen Aufgaben. Die Liste der bereits abgeschlossenen Aufgaben ist leer.
Um zwei komplexe Typen T1 und T2 zu vergleichen:
Überprüfen Sie die Attributgruppen, die für T1 und T2 für eine Subset / Superset-Beziehung zwischen ihren Namen deklariert wurden. Stellen Sie sicher, dass kein für die beabsichtigte Obermenge erforderliches Attribut in der beabsichtigten Untergruppe fehlt oder optional ist.
Jedem für T1 und T2 deklarierten Attribut A wird ein Typ zugewiesen (nennen Sie sie ST1 und ST2). Wenn ST1 = ST2, nichts tun; Andernfalls fügen Sie die Aufgabe "Vergleiche einfache Typen ST1 und ST2" zur Warteschlange der offenen Aufgaben hinzu, es sei denn, sie befindet sich in der Liste der bereits abgeschlossenen Vergleiche.
Überprüfen Sie nun die Sequenzen von Kindern, die in T1 und T2 möglich sind. Wie in einem Kommentar angedeutet, ist dies handhabbar, da Inhaltsmodelle im Wesentlichen reguläre Ausdrücke sind, die die Menge der Elementnamen als Alphabet verwenden; Die Sprachen, die sie definieren, sind daher regelmäßig, und die Subset / Superset-Beziehung ist für reguläre Sprachen entscheidbar.
Jedem möglichen untergeordneten Element C wird sowohl eine Elementdeklaration als auch eine Typdefinition durch die übergeordneten Typen T1 und T2 zugewiesen. Nennen wir sie ED1, ED2, CT1 und CT2. Jedes untergeordnete Objekt mit demselben Namen hat denselben Typ, aber unterschiedliche untergeordnete Elemente können unterschiedliche Elementdeklarationen enthalten. Für jeden möglichen Namen gibt es nur ein Paar der Typen CT1 und CT2, aber es können mehrere Paare ED1 und ED2 vorhanden sein (und die Analyse muss sorgfältig sein, um sicherzustellen, dass sie korrekt übereinstimmen; das könnte schwierig sein automatisieren).
Wenn CT1 = CT2, nichts tun, andernfalls "Vergleiche die Typen CT1 und CT2" in die offene Task-Warteschlange, es sei denn, der Vergleich wurde bereits durchgeführt.
Wenn ED1 und ED2 strukturell identisch sind, tun Sie nichts; Andernfalls wird die Aufgabe gestellt, sie in die Aufgabenwarteschlange zu vergleichen (sofern dies nicht bereits geschehen ist).
Um zwei einfache Typen ST1 und ST2 zu vergleichen, vergleichen Sie entweder ihre lexikalischen Leerzeichen (wenn Sie die erste Definition der Untermengen- / Obermengenbeziehung für Schemas wollen) oder ihre Wertebereiche (wenn Sie die zweite wollen). Wenn ST1 und ST2 beide Einschränkungen desselben primitiven Typs sind, können Sie die Menge der effektiven facettenbasierten Einschränkungen für diese einfach vergleichen. Die Musterfacette kann Dinge komplizieren, aber da sie eine Menge regulärer Ausdrücke definiert, ist die Subset / Superset-Beziehung dafür entscheidbar.
Um zwei Elementdeklarationen zu vergleichen, müssen Sie jede der Eigenschaften für die Elementdeklaration vergleichen und nach der gewünschten Subset / Superset-Beziehung suchen.
Wie Sie sehen können, ist es komplex und langwierig genug, dass Sie diese Analyse wirklich automatisieren möchten, und es ist auch komplex genug, dass es leicht zu verstehen ist, warum es nicht als Standardfunktion angeboten wird. Aber es wäre sicherlich interessant zu programmieren.
Danke, @ 13ren, für Ihren "Piep":)
Dies ist ein langer Kommentar und keine Antwort. Ich beginne mit meinem früheren Austausch mit 13ren, more precise, it provides to a user all that is needed to define such an analysis model.
Was ich meinte ist, dass in QTAssistant ( dieser ) wir einen XSD Vergleich haben Funktion; Da es XSD-fähig ist, gibt es bereits viele Dinge, die ein Text- oder XML-fähiges Diff-Tool nicht tun kann (z. B. ist es egal, wie viele XSD-Dateien, ihr Layout zwischen den Versionen geändert wird). Die Diff-Engine arbeitet gegen das Quellmodell, im Gegensatz zur PSVI-Version. Wir könnten es anpassen, um stattdessen das PSVI zu verwenden, da Letzteres einen Schritt näher an dem ist, was Sie tatsächlich benötigen. Wir könnten auch die Möglichkeit einschließen, dass ein benutzerdefinierter Regelsatz den Vergleich zwischen "Basis" und "Revision" erweitert, mit anderen Worten, um dem Benutzer zu ermöglichen, den "=" Operator, den wir gerade verwenden, zu überschreiben.
Ich erkenne, dass wir nichts aus der Box haben, um den Vergleich von xsd: pattern-Facetten zu überschreiben; noch für etwas, das für einen Menschen einfach zu erkennen ist, wie xsd:positiveInteger
vs. xsd:integer + xsd:minInclusive=1
. Oder ein xsd:all
mit einem xsd:choice
oder xsd:sequence
vergleichen; und für dasselbe selektionieren wir keine Selektoren und Felder für XSD-Constraints, die ähnlich wie reguläre Ausdrücke nicht leicht zu handhaben wären.
Unter der Annahme, dass es das Ziel ist, so viele "Diskrepanzen" wie möglich zu finden, anstatt sie vollständig auszuschließen, hat QTAssistant drei weitere nützliche Funktionen:
Eine andere Sache, für die wir in unserem Vergleich vorsorgen mussten (und die Sie vielleicht in Erwägung ziehen), hatte mit der Äquivalenz nicht nur der XSD / XML zu tun, sondern auch der von XSD erzeugten Artefakte (z. B. Java-Klassen über JAXB); um das Ganze abzurunden, Erweiterbarkeitsmuster, solche, die Platzhalter verwenden (xsd: any und anyAttribute).
Wir (QTAssistant) sind derzeit daran interessiert, mit Ihnen durch einige spezifischere Anforderungen zusammenzuarbeiten (wir müssten mit einem Austausch von repräsentativen XSDs, NDAs, die ich annehmen würde, etc.), Out-of-Band, um zu sehen, ob wir es tatsächlich tun könnte es funktionieren lassen. Wenn Sie fortfahren möchten, kontaktieren Sie mich bitte über die Support-Adresse der Website, die mit meinem SO-Profil verknüpft ist.
Da es derzeit keine verfügbare Lösung für das Validieren / Prüfen eines Schemas gegen ein anderes Schema gibt, sieht es so aus, als müssten wir Workarounds verwenden. Unten ist mein Versuch.
Wiederherstellung des Problems:
Identifizieren Sie, ob alle in einem Teilmengenschema definierten Datentypen vorhanden sind und innerhalb der (weniger strengeren) Grenzen dessen sind, was in einem "Blueprint" -Schema definiert ist.
Eine mögliche Lösung:
Mit diesem Wissen können wir also eine Lösung konstruieren:
Erstellen Sie alle möglichen XML-Instanzen eines Subset-Schemas (das Ausführen dieses Schritts kann eine Herausforderung sein) und validieren Sie diese XML-Instanzen anhand des "Blueprint" -Schemas.
Aber wie wissen Sie, dass das Teilmengenschema eine Teilmenge eines "Blueprint" Schemas ist? Nun, da Sie alle möglichen XML-Instanzen eines Subset-Schemas erstellt haben, wurden alle Datentypen abgedeckt, die in einem Subset-Schema vorhanden sind. Und diese XML-Instanzen gegen das "Blueprint" -Schema zu validieren, prüft inhärent, ob die Datentypen existieren und alles innerhalb der Grenzen dessen ist, was in dem "Blueprint" -Schema definiert ist. Daher identifizieren Sie, dass Ihr Subset-Schema tatsächlich eine Teilmenge eines "Blueprint" -Schemas ist.
Ich weiß, es ist keine ideale Lösung, aber ich hoffe, dies hilft, da es keine einfache Möglichkeit gibt, das zu tun, was Sie fragen.
Werkzeuge, die XML gegen ein Schema validieren, wissen bereits, wie dies zu tun ist, denn im Fall von <xs:complexContent><xs:restriction>
muss der neu definierte Typ eine Teilmenge des Typs sein, der eingeschränkt wird.
Wenn Sie diese Funktionalität nutzen möchten, können Sie in den untergeordneten Schemas komplexe Typen definieren, die Typen in Ihrem Blueprint-Schema einschränken.
Wenn die untergeordneten Schemas jedoch ohne diese Absicht erstellt werden, könnte dies möglicherweise noch erreicht werden, indem die untergeordneten Schemas so geändert werden, dass sie mit dem unten stehenden Muster übereinstimmen, und dann zur Überprüfung durch einen Schema-Prozessor gesendet werden.
Beispiel für ein Blueprint-Schema, blueprintschema.xsd:
%Vor%Beispiel eines untergeordneten Schemas, das eine Teilmenge des Blueprint-Schemas ist:
%Vor%Beispiel für ein untergeordnetes Schema nach der Umwandlung in ein neudefiniertes Konstrukt:
%Vor%Ein Schema-Prozessor teilt Ihnen dann mit, ob der neu definierte "rootType" tatsächlich eine Teilmenge des ursprünglichen Blueprints "rootType"
istDa ein Schema nur XML ist, kann die Umwandlung mit normalen XML-Verarbeitungstools erfolgen.
Tags und Links xsd validation subset schema