Gängige Muster

(Auszug aus "XML Schema" von Eric van der Vlist)

Nach diesem Überblick über die für Muster verwendeten Schreibweisen sollten wir uns nun einige gängige Muster ansehen, die Sie vielleicht in Ihren Schemas verwenden (oder anpassen) müssen, die Sie aber auch einfach als Beispiele betrachten können.

String-Datentypen

Reguläre Ausdrücke behandeln Informationen in ihrer Darstellung als Text. Das macht sie zu einem ausgezeichneten Mechanismus für die Einschränkung von Strings.

Unicode-Blöcke

Unicode ist ein großes Plus bei XML; es gibt jedoch wenige Anwendungen, die alle Zeichen des Unicode-Satzes ordnungsgemäß verarbeiten und anzeigen können, und noch weniger Anwender, die sie dann auch lesen können. Wenn Sie prüfen müssen, daß Ihre String-Datentypen zu einem (oder mehreren) Unicode-Blöcken gehören, können Sie sie von grundlegenden Typen wie den folgenden ableiten:

<xs:simpleType name="BasicLatinToken">
  <xs:restriction base="xs:token">
    <xs:pattern value="\p{IsBasicLatin}*"/>
  </xs:restriction>
</xs:simpleType>
<xs:simpleType name="Latin-1Token">
  <xs:restriction base="xs:token">
    <xs:pattern value="[\p{IsBasicLatin}\p{IsLatin-1Supplement}]*"/>
  </xs:restriction>
</xs:simpleType>

Beachten Sie, daß solche Muster dem Dokument keine spezielle Zeichensatz-Codierung auferlegen und daß beispielsweise der Datentyp Latin-1Token Instanzdokumente in UTF-8, UTF-16, ISO-8869-1 oder anderen Codierungen validieren kann. (Dabei nehmen wir an, daß die in diesem String verwendeten Zeichen zu den zwei Unicode-Blöcken BasicLatin und Latin-1Supplement gehören.) Anders ausgedrückt, kontrollieren diese Muster nicht das physische Format der Instanzdokumente, da sie auf dem lexikalischen Raum arbeiten, d.h., nachdem der Parser seine Transformationen ausgeführt hat.

Wörter zählen

Wir haben bereits einen Trick gesehen, wie man mit Hilfe einer Dummy-Ableitung durch Aufzählung die Wörter zählen kann. Diese Ableitung zählt jedoch nur Whitespace-getrennte Wörter und ignoriert Interpunktionszeichen, die sie wie normale Zeichen behandelt. Wir können die Wortzahl durch einige Muster einschränken. Dazu können wir ein Atom definieren, das eine Folge von einem oder mehreren »Wort«-Zeichen (\w+) ist, der ein oder mehrere Nicht-Wort-Zeichen (\W+) folgen, und dann können wir angeben, wie oft dieses Atom auftreten darf. Wenn wir bei der Interpunktion nicht sehr streng sind, müssen wir auch zulassen, daß eine beliebige Anzahl von Nicht-Wort-Zeichen am Anfang unseres Werts steht, und wir müssen damit rechnen, daß ein Wert mit einem Wort (ohne nachfolgende Trennzeichen) steht. Eine der Methoden, jede Mehrdeutigkeit am String-Ende zu vermeiden, besteht darin, das letzte Auftreten eines Worts getrennt aufzuführen und dann die Trennzeichen am Ende optional zu machen:

<xs:simpleType name="story100-200words">
  <xs:restriction base="xs:token">
    <xs:pattern value="\W*(\w+\W+){99,199}\w+\W*"/>
  </xs:restriction>
</xs:simpleType>

URIs

Wie bereits erfahren, kümmert Einschränkungen sich nicht darum, relative URIs absolut zu machen, und daher kann es klug sein, die Verwendung absoluter URIs, die leichter zu verarbeiten sind, zu verlangen. Darüber hinaus kann es für einige Anwendungen auch interessant sein, die akzeptierten URI-Schemata einzuschränken. Dies wird leicht mit einem Muster wie dem folgenden erreicht:

<xs:simpleType name="httpURI">
  <xs:restriction base="xs:anyURI">
    <xs:pattern value="http://.*"/>
  </xs:restriction>
</xs:simpleType>

Numerische und Gleitkommatypen

Auch wenn numerische Typen strenggenommen keine Texte sind, können Muster dennoch in geeigneter Form verwendet werden, um ihre lexikalische Darstellung einzuschränken.

Führende Nullen

Führende Nullen loszuwerden ist ziemlich einfach, erfordert jedoch einige Vorsichtsmaßnahmen, wenn wir das optionale Vorzeichen und die Zahl »0« selbst behalten wollen. Das läßt sich mit Mustern wie dem folgenden erreichen:

<xs:simpleType name="noLeadingZeros">
  <xs:restriction base="xs:integer">
    <xs:pattern value="[+-]?([1-9][0-9]*|0)"/>
  </xs:restriction>
</xs:simpleType>

In diesem Muster haben wir uns dafür entschieden, sämtliche lexikalischen Regeln, die für eine ganze Zahl zutreffen, neu zu definieren. Dieses Muster würde bei Anwendung auf den Datentyp xs:token denselben lexikalischen Raum ergeben wie bei einem xs:integer. Wir hätten uns auch auf die Kenntnis des Basisdatentyps verlassen und das folgende schreiben können:

<xs:simpleType name="noLeadingZeros">
  <xs:restriction base="xs:integer">
    <xs:pattern value="[+-]?([^0].*|0)"/>
  </xs:restriction>
</xs:simpleType>

Wenn man sich in dieser Weise auf den Basis-Datentyp verläßt, kann das zu einfacheren Mustern führen; es kann andererseits auch schwerer zu interpretieren sein, da wir die lexikalischen Regeln für den Basis-Datentyp und die durch das Muster formulierten Regeln miteinander kombinieren müßten, um das Ergebnis zu verstehen.

Festes Format

Die maximale Anzahl von Ziffern kann mit xs:totalDigits und xs:fractionDigits festgelegt werden. Diese Facetten sind jedoch nur Maximalzahlen und operieren außerdem auf dem Werteraum. Wenn wir das Format des lexikalischen Raums beispielsweise auf »DDDD.DD« festlegen wollen, können wir ein solches Muster schreiben:

<xs:simpleType name="fixedDigits">
  <xs:restriction base="xs:decimal">
    <xs:pattern value="[+-]?.{4}\..{2}"/>
  </xs:restriction>
</xs:simpleType>

Datum und Uhrzeit

Datums- und Uhrzeitangaben haben komplizierte lexikalische Darstellungen. Entwickler können mit Mustern zusätzlich steuern, wie sie verwendet werden.

Zeitzonen

Die Unterstützung von W3C XML Schema für Zeitzonen ist einigermaßen kontrovers. Sie bedarf zusätzlicher Einschränkungen, um Probleme beim Vergleich zu vermeiden. Diese Muster können vergleichsweise einfach gehalten werden, weil die Syntax für Datums-/Zeitangaben bereits vom Schema-Validierer geprüft wird und nur einfache zusätzliche Prüfungen hinzugefügt werden müssen. Anwendungen, die verlangen, daß ihre Datums-/Zeitangaben eine Zeitzone enthalten, können die folgende Vorlage verwenden, die überprüft, daß der Uhrzeitteil mit einem »Z« endet oder aber ein Vorzeichen enthält:

<xs:simpleType name="dateTimeWithTimezone">
  <xs:restriction base="xs:dateTime">
    <xs:pattern value=".+T.+(Z|[+-].+)"/>
  </xs:restriction>
</xs:simpleType>

Noch einfacher können Anwendungen, die sicherstellen wollen, daß keine ihrer Datums-/Zeitangaben eine Zeitzone enthält, lediglich prüfen, daß der Uhrzeitteil nicht die Zeichen »+«, »-« oder »Z« enthält:

<xs:simpleType name="dateTimeWithoutTimezone">
  <xs:restriction base="xs:dateTime">
    <xs:pattern value=".+T[^Z+-]+"/>
  </xs:restriction>
</xs:simpleType>

Bei diesen beiden Datentypen haben wir das Trennzeichen »T« verwendet. Das ist praktisch, weil Vorzeichen nach diesem Trennzeichen außer in der Zeitzonenangabe nicht mehr auftreten dürfen. Dieses Trennzeichen würde jedoch fehlen, wenn wir Datumsangaben anstelle von Datums-/Zeitangaben einschränken wollten. In diesem Fall können wir die Zeitzone jedoch statt dessen anhand ihres »:« erkennen:

<xs:simpleType name="dateWithTimezone">
  <xs:restriction base="xs:date">
    <xs:pattern value=".+[:Z].*"/>
  </xs:restriction>
</xs:simpleType>
<xs:simpleType name="dateWithoutTimezone">
  <xs:restriction base="xs:date">
    <xs:pattern value="[^:Z]*"/>
  </xs:restriction>
</xs:simpleType>

Anwendungen können auch einfach eine Reihe zulässiger Zeitzonen vorschreiben:

<xs:simpleType name="dateTimeInMyTimezones">
  <xs:restriction base="xs:dateTime">
    <xs:pattern value=".+\+02:00"/>
    <xs:pattern value=".+\+01:00"/>
    <xs:pattern value=".+\+00:00"/>
    <xs:pattern value=".+Z"/>
    <xs:pattern value=".+-04:00"/>
  </xs:restriction>
</xs:simpleType>

Wir haben weiter vorn versprochen, xs:duration zu betrachten und herauszufinden, wie man zwei Datentypen definieren kann, die total geordnet sind. Der erste Datentyp wird aus Zeitdauern bestehen, die nur in Monaten und Jahren ausgedrückt sind, und der zweite wird aus Zeitdauern bestehen, die nur in Tagen, Stunden, Minuten und Sekunden ausgedrückt sind. Das Kriterium für den Test kann das Vorhandensein von »D« (für Tage) oder »T« (das Zeittrennzeichen) sein. Wenn keines dieser Zeichen auftritt, benutzt der Datentyp nur den Jahres- und den Monatsteil. Der Test auf den anderen Typ kann nicht auf der Abwesenheit von »Y« und »M« beruhen, da es auch im Uhrzeitteil ein »M« gibt. Wir können jedoch prüfen, ob das erste Feld nach einem optionalen Vorzeichen entweder der Tagesteil oder aber das Trennzeichen »T« ist:

<xs:simpleType name="YMduration">
  <xs:restriction base="xs:duration">
    <xs:pattern value="[^TD]+"/>
  </xs:restriction>
</xs:simpleType>
<xs:simpleType name="DHMSduration">
  <xs:restriction base="xs:duration">
    <xs:pattern value="-?P((\d+D)|T).*"/>
  </xs:restriction>
</xs:simpleType>

   

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema XML Schema bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2003 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XML Schema" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de