# Gegenseitig ausschließende Attribute definieren in XSD



## Milo (25. Feb 2011)

Hallo,

ich befasse mich gerade ein wenig mit XML. Bin jedoch noch nicht bei der eigentlichen Programmierung in JAVA sondern bei der Schemadefinition. Hier habe ich ein kleines Problem, wo ich nicht weiter komme. Möglicherweise sehe ich das mit dem Schema auch zu eng, sodass man das ganze besser programmtechnisch Lösen sollte als durch die XSD - in jedem Fall würde ich mich über ein paar Hinweise und Anregungen freuen, bevor ich mich da verrenne.

Konkret geht es um das Erstellen einer Schemadatei (XSD). Ich möchte erreichen, dass sich innerhalb eines Elements zwei Attribute gegenseitig ausschließen - also nicht den selben Wert zugewiesen bekommen. Ein einfaches Beispiel soll das mal beschreiben.

```
<orte>
  <ort pid="1" name="Berlin" />
  <ort pid="2" name="Hamburg" />
  <ort pid="3" name="München" />
</orte>

<reise>
  <reiseweg from="1" to="2" />
  <reiseweg from="2" to="3" />
  <reiseweg from="1" to="3" />
  <reiseweg from="2" to="2" /> <!-- dieses soll unterbunden werden -->
</reise>
```

Zum Beschreiben einer Route gibt es Orte mit einer eindeutigen ID (key). Diese Schlüssel können innerhalb von from und to beim Element reiseweg eingetragen werden. Dies funktioniert soweit auch ganz gut, da ich hier mit key und keyref arbeiten kann. Meine bisherige XSD sieht somit wie folgt aus:

```
<xsd:key name="keyPid">
  <xsd:selector xpath=".//ort"/>
  <xsd:field xpath="@pid"/>
</xsd:key>
 
<xsd:keyref name="keyrefPidTo" refer="oa:keyPid">
  <xsd:selector xpath=".//reiseweg"/>
  <xsd:field xpath="@to"/>
</xsd:keyref>
 
<xsd:keyref name="keyrefPidFrom" refer="oa:keyPid">
  <xsd:selector xpath=".//reiseweg"/>
  <xsd:field xpath="@from"/>
</xsd:keyref>
```

Was ich damit jedoch nicht erreiche ist, dass ich Einträge wie bspw.: <reiseweg from="2" to="2" />, bei denen from = to ist, unterbinde. Gibt es eine Möglichkeit, so etwas innerhalb des Schemas festzulegen?

Bisher eingefallen ist mir der theoretische Umweg über eine Transformation. Innerhalb der XSLT könnte ich letztlich abfragen, ob from != to ist und nur diese Elemente berücksichtigen. Das könnte also so aussehen:


```
<xsl:template match="reiseweg">
  <xsl:if test="./@from != ./@to">
    <xsl:copy>
      <xsl:apply-templates select="@*|*|text()" />
    </xsl:copy>
  </xsl:if>
</xsl:template>
```

Grundsätzlich wäre mir jedoch eine Lösung ohne XSLT lieber, da ich bei der Transformation aufpassen muss, dass nicht an anderer Stelle durch diese Reduktion invalides XML erzeugt wird.

Über ein paar Anregungen freue ich mich!

Gruß Micha


----------



## Wildcard (27. Feb 2011)

Ist mit XSD 1/1.1 unmöglich. Erst mit Schema Aufsätzen wie Schematron oder dem Draft für XSD 2.0 sind Constraints möglich die sich über mehr als einen Wert erstrecken.
Arbeitest du später mit XML Binding um daraus zB Java Objekte zu erstellen? Wenn ja, dann geht das gut mit EMF indem du wahlweise einen ensprechenden EMF Validator schreibst, oder eine OCL Regel in dein Modell aufnimmst.


----------



## Milo (28. Feb 2011)

Hallo Wildcard,

erstmal vielen Dank für Deine Rückmeldung. Hatte schon befürchtet, das ich "leer" ausgehe. Das Schematron ist, wenn ich es richtig verstanden habe, mit einer XSLT vergleichbar. Der Unterschied liegt wohl im Ergebnis. Nach der Transformation habe ich eine neue XML. Beim Schematron nur die Aussage, ob diese korrekt ist, oder? 

Ich habe mir für die Umsetzung bisher noch keine großen Gedanken gemacht, da ich bei dem Problem mit der XSD erstmal gestoppt bin. Ich habe ein wenig mit dem XML-Hammer rumprobiert. Dort habe ich eine Schaltfläche gefunden, hinter der sich Java-Code verbirgt. Hast Du Erfahrungen mit dem Programm? Ist dieser Code brauchbar? Ich hätte vermutlich mir ein paar gezielte XPATH-Ausdrücke überlegt, um an meine Daten später zu kommen. Hierfür würde mir der Hammer sicher einiges an Arbeit abnehmen.

Viele Deiner Abkürzungen sagen mit leider nichts. Wie ich schon schrieb, befasse ich mich jetzt erst etwas intensiver mit XML. Über ein paar Tipps bin ich also dankbar!

Gruß Micha


----------



## Wildcard (28. Feb 2011)

> Hast Du Erfahrungen mit dem Programm?


Noch nie davon gehört.
Wenn du XML Dateien die einem Schema genügen einlesen, verarbeiten, oder speichern möchtest, dann verwendet man dazu normalerweise ein XML Binding Framework.
Das Framework überführt die XML Datei dabei in Java Objekte. Die entsprechenden Klassen lässt man sich normalerweise automatisch aus dem XML Schema erzeugen.
EMF ist wohl das beste Werkzeug in dem Bereich, alternativ steht Jaxb zur Verfügung das bereits im JDK enthalten ist, aber über deutlich weniger Features verfügt.
http://www.eclipse.org/modeling/emf/


----------



## Milo (2. Mrz 2011)

Hallo Wildcard,

vielen Dank für Deine Antwort. ICh werde mir EMF anschauen, wenn ich mein Schema fertig habe. Ich bin mir aktuell noch unschlüssig, wie ich weiter verfahren soll. Aber vll kannst Du mir noch eine grundsätzliche Frage beantworten: Wenn eine XSLT in der XML eingebunden ist, würde mir ein PARSER dann das Original oder die transformierte Datei zurückliefern?

Gruß Micha


----------



## Wildcard (3. Mrz 2011)

Ein Parser ist kein XSLT Prozessor, er wird dir immer nur den Inhalt des Dokuments parsen.


----------



## Milo (6. Mrz 2011)

Moin Wildcard,

vielen Dank für Deine Hilfe. Ich denke, um eine Prüfung innerhalb des Programms komme ich so oder so nicht drum herum. Für XSD bin ich noch auf das Element [XML]assert[/XML] gestoßen, welches wohl mit Version 1.1 kommen soll/gekommen ist!? Leider ist es mir nicht geglückt, dieses so einzusetzen, dass bspw. der XML-Hammer es akzeptiert (was ggf. auch daran liegt, dass dieser noch keine Version über 1.0 unterstützt).

[XML]<xsd:assert test="@from ne @to" />[/XML]

In jedem Fall schon mal vielen Dank für Deine Hilfe. Ich werde sicher bei der Umsetzung später noch ein paar Fragen haben ;-)

Schönen Sonntag
Micha


----------



## Wildcard (7. Mrz 2011)

> gestoßen, welches wohl mit Version 1.1 kommen soll/gekommen ist!? Leider ist es mir nicht geglückt, dieses so einzusetzen, dass bspw. der XML-Hammer es akzeptiert (was ggf. auch daran liegt, dass dieser noch keine Version über 1.0 unterstützt).


Ja, mein Fehler, ich schrieb XSD 2.0, aber der Draft hat die Version 1.1. Damit wird soetwas möglich werden, aber noch ist die Spec AFAIK nicht released.


----------

