2016-06-07 9 views
0

Ich versuche, eine XSD zu generieren, um eine XML mit einer unbekannten Tiefe zu validieren. Dies geschieht über ein XSLT aus einem XML. Der XML-Code ist wie eine Klassenbeschreibung strukturiert und jeder Knoten enthält Informationen über die Attribute und Childs. Das XSD muss ein anderes XML überprüfen, das die Instanzen enthält. Daher muss das XSD überprüfen, ob eine Instanz alle Attribute von ihrer Klasse und ihren Vorfahren hat.XSD Probleme mit Erweiterung über mehrere Ebene

Deshalb habe ich versucht, mein Problem mit Typen zu lösen, die sich gegenseitig erweitern.

XML-Testdatei:

<!-- language:xml --> 
<?xml version="1.0" encoding="UTF-8"?> 
<CAEXFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      FileName="Visu_Ruehrreaktor.aml" 
      SchemaVersion="2.15" 
      xsi:noNamespaceSchemaLocation="Validation.xsd"> 
    <HMI> 
     <HMIGraphic Name="Visu_Ruehrreaktor" 
        RefBaseSystemUnitPath="HMISUCLib/Graphic" 
        ID="dce863ca-795b-4d54-9a4c-789b0204f243"> 
     <h>1080</h> 
     <w>1920</w> 
     <HMIVisuObjectTextBoxTermination Name="Text01" 
              RefBaseSystemUnitPath="HMISUCLib/VisuObject/TextBox/Termination" 
              ID="c0215848-b8b6-4f76-aa2c-3996a053f3fc"> 
      <text/> 
      <tagname>Text01</tagname> 
      <x>178</x> 
      <y>152</y> 
      <h>37</h> 
      <w>139</w> 
      <role/> 
      <type>0001</type> 
      <rotation>01</rotation> 
      <com_id/> 
     </HMIVisuObjectTextBoxTermination> 
     </HMIGraphic> 
    </HMI> 
</CAEXFile> 

XSD:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:fn="http://www.w3.org/2005/xpath-functions"> 
    <xs:complexType name="HMI_type"> 
     <xs:choice maxOccurs="unbounded"> 
     <xs:element name="HMIGraphic" type="HMIGraphic_type" minOccurs="0"/> 
     </xs:choice> 
    </xs:complexType> 

    <xs:complexType name="HMIVisuObject_type"> 
     <xs:choice maxOccurs="unbounded"> 
     <xs:element name="tagname" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="x" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="y" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="h" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="w" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="role" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="type" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="rotation" minOccurs="1" maxOccurs="1"/> 
     </xs:choice> 
     <xs:attribute name="Name" type="xs:string" use="required"/> 
     <xs:attribute name="RefBaseSystemUnitPath" type="xs:string" use="required"/> 
     <xs:attribute name="ID" type="xs:string" use="required"/> 
    </xs:complexType> 

    <xs:complexType name="HMIVisuObjectTextBox_type"> 
     <xs:complexContent> 
     <xs:extension base="HMIVisuObject_type"> 
      <xs:choice maxOccurs="unbounded"> 
       <xs:element name="text" minOccurs="1" maxOccurs="1"/> 
      </xs:choice> 
     </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 
    <xs:complexType name="HMIVisuObjectTextBoxTermination_type"> 
     <xs:complexContent> 
     <xs:extension base="HMIVisuObjectTextBox_type"> 
      <xs:choice maxOccurs="unbounded"> 
      </xs:choice> 
     </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 
    <xs:complexType name="HMIGraphic_type"> 
     <xs:choice maxOccurs="unbounded"> 
     <xs:element name="HMIVisuObject" type="HMIVisuObject_type" minOccurs="0"/> 
     <xs:element name="HMIVisuObjectTextBox" 
        type="HMIVisuObjectTextBox_type" 
        minOccurs="0"/> 
     <xs:element name="HMIVisuObjectTextBoxTermination" 
        type="HMIVisuObjectTextBoxTermination_type" 
        minOccurs="0"/> 
     <xs:element name="h" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="w" minOccurs="1" maxOccurs="1"/> 
     </xs:choice> 
     <xs:attribute name="Name" type="xs:string" use="required"/> 
     <xs:attribute name="RefBaseSystemUnitPath" type="xs:string" use="required"/> 
     <xs:attribute name="ID" type="xs:string" use="required"/> 
    </xs:complexType> 

    <xs:element name="CAEXFile"> 
     <xs:complexType> 
     <xs:all> 
      <xs:element name="HMI" type="HMI_type" minOccurs="0"/> 
     </xs:all> 
     <xs:anyAttribute processContents="skip"/> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

Das Problem ist, wann immer ich die Validierung laufen und ein Element des Typs HMIVisuObjectTextBoxTermination_type ich sagen, erhalten Sie einen Fehler finden, dass Der Text ist nicht als Element zulässig.

Ausgabe/To_Check.aml: 15: Elementtext: Schema-Gültigkeitsfehler: Element 'text': Dieses Element wird nicht erwartet. Erwartet wird (Tagname, x, y, h, w, Rolle, Typ, Rotation).

Also im Grunde nur die Elemente des Wurzelelements dieser Kette von Typen. Was mache ich falsch und wie kann ich dieses Problem lösen?

Vielen Dank im Voraus

+0

Beide Dateien hinzugefügt. Ich hoffe, es hilft. – Tyreal

Antwort

0

Ihr komplexer Typ HMIVisuObjectTextBoxTermination_type wahrscheinlich ein wirksames Inhaltsmodell hat, das nicht das, was Sie erwarten. In XSD 1.0 erstellt die Erweiterung eines komplexen Typs eine Sequenz, die zunächst das Inhaltsmodell des Basistyps und dann das von der Erweiterung hinzugefügte Material enthält. (Manche Leute finden es hilfreich, dies als analog zum Hinzufügen neuer Felder am Ende einer Struktur zu sehen, in Erweiterungen zu Basisklassen in OO-Sprachen.) Da Sie eine Erweiterung einer Erweiterung haben, haben Sie, was Sie haben, in Wirkung:

<xs:sequence> 
    <!--* complex type HMIVisuObjectTextBox_type *--> 
    <xs:sequence> 
    <!--* complex type HMIVisuObject_type *--> 
    <xs:choice maxOccurs="unbounded"> 
     <xs:element name="tagname" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="x" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="y" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="h" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="w" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="role" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="type" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="rotation" minOccurs="1" maxOccurs="1"/> 
    </xs:choice> 
    <xs:choice maxOccurs="unbounded"> 
     <xs:element name="text" minOccurs="1" maxOccurs="1"/> 
    </xs:choice> 
    </xs:sequence> 
    <xs:choice maxOccurs="unbounded"> 
    </xs:choice> 
</xs:sequence> 

gültige Instanzen von Sequenzen von Elementen, die die Verkettung von drei Subsequenzen, das Spiel enthalten:

  • zuerst ein oder mehrere des Tag-Namen, x, y, h, w, Rolle, Typ oder Rotation, gefolgt von
  • ein oder mehrere von Text, gefolgt von
  • eine oder mehrere der leeren Menge.

Sie haben zwei Probleme: Erstens, indem Sie Ihre XML zu urteilen, Sie text in der wiederholbaren Wahl der Menge der möglichen Kinder hinzugefügt werden erwartet, erforderlich werden nicht nach all den anderen zu kommen. Zweitens ist eine Auswahl in einem Inhaltsmodell erfüllt, wenn das nächste Eingabeelement mit einem seiner untergeordneten Elemente übereinstimmt; Eine leere Auswahl hat keine Kinder, daher kann nichts mit ihnen übereinstimmen. Wenn die Wahl als dritte Wahl in dieser Reihenfolge erforderlich ist, ist die Wahl unerfüllbar. Das bedeutet hier, dass seine enthaltende Sequenz unerfüllbar ist, was wiederum bedeutet, dass seine enthaltende Sequenz unerfüllbar ist, was wiederum bedeutet, dass der Typ HMIVisuObjectTextBoxTermination_type keine gültigen Instanzen hat. Wenn Sie die Option minOccurs="0" wählen, kann der Typ gültige Instanzen haben, aber das Element text darf nicht an erster Stelle stehen.

[Nachtrag] OP fragt: "Gibt es also eine andere Art und Weise als ... zu versuchen, meine XSLT rekursiv in einer Weise, die ich kopieren alle Eltern Attribute und erstellen Sie eine neue Art zu machen? Was ich will, im Grunde Do fügt Text tatsächlich zur Liste der Auswahlmöglichkeiten hinzu, da sie alle in XML vorhanden sein müssen, aber sie können in beliebiger Reihenfolge vorliegen. "

Mehrere mögliche Ansätze bieten sich:

  • eine feste Reihenfolge für die Kinder an. Wenn die Reihenfolge der untergeordneten Elemente festgelegt ist, wird das Typherleitungsproblem trivial.

    Also würde ich sehr sorgfältig die Prämisse untersuchen, dass die Reihenfolge der Kinder uneingeschränkt sein muss; das wird viel häufiger behauptet als es wahr ist. Es ist wahr, wenn die Folge von Kindern Informationen enthält (wie es normalerweise in Dokumenten in natürlicher Sprache der Fall ist); es ist suspekt, wenn die Sequenz keine Informationen enthält.

  • Definieren Sie benannte Modellgruppen für die Auswahlen jetzt in HMIVisuObject_type, HMIVisuObjectTextBox_type usw. Definieren Sie die verschiedenen fraglichen Typen als Auswahlen unter den entsprechenden benannten Modellgruppen.

    Dies zeigt die Beziehung zwischen den drei Arten deutlich zu einem menschlichen Leser, und vermeidet mehrere Spezifikationen der gleichen Sache. Es zeigt die Beziehung nicht anhand der Beziehung vom Basistyp/abgeleiteten Typ zwischen den Typen, und in einigen Umgebungen ist es weniger hilfreich. (Aber wenn Sie auf eine Zuordnung zu einem OO-Klassensystem angewiesen wären, würden Sie keine wiederholbaren Auswahlen an erster Stelle verwenden. Das ist Ihnen wahrscheinlich egal, obwohl es für einige Benutzer von Bedeutung ist.)

  • Kehren Sie die Typhierarchie um: Definieren Sie Ihren umfassendsten Typ als Typ und die anderen als Einschränkungen.

    Dies zeigt die Beziehung zwischen den Typen unter Verwendung von Base/Derived-Links, aber die gerichteten Links möglicherweise nicht in der Richtung, die Sie bevorzugen würden.

  • Wenn Sie XSD 1.1 verwenden, ersetzen Sie die Auswahlmöglichkeiten in diesen Typen durch alle Gruppen; In XSD 1.1 erzeugt ein Basistyp mit einer Allgroup, die um eine Allgroup erweitert wird, eine größere Allgroup.

+0

Das klingt nicht so gut, aber danke bis jetzt! Okay, der leere Satz konnte in meinem XSLT behoben werden. Aber das behebt mein Problem mit der Sequenz nicht. Gibt es also einen anderen Weg als zu versuchen, meine XSLT rekursiv in einer Weise zu machen, dass ich alle Eltern Attribute kopieren und einen neuen Typ erstellen und Lösungen vergessen? Was ich eigentlich tun möchte, ist tatsächlich Text zur Liste der Auswahlmöglichkeiten hinzufügen, weil sie alle in XML vorhanden sein müssen, aber sie könnten in beliebiger Reihenfolge sein. – Tyreal

Verwandte Themen