2012-03-27 9 views
0

Ich möchte, dass meine XSD den Inhalt einer Zeichenfolge überprüft. Um genau zu sein, möchte ich validieren, dass eine bestimmte Zeichenfolge nicht auftritt.XSD-Einschränkung, die eine übereinstimmende Zeichenfolge negiert

Betrachten Sie diese Regel, die überprüfen, ob meine Zeichenfolge auftritt. Suche nach allen Link Elemente beginnt mit diesem string: /site/example.com

<xs:element name="Link" type="xs:normalizedString" minOccurs="0"> 
    <xs:simpleType> 
    <xs:restriction base="xs:token"> 
     <xs:pattern value="(/site/example\.com).*"/> 
    </xs:restriction> 
    </xs:simpleType> 
</xs:element>     

Mit anderen Worten, überprüft der obige Ausdruck, dass alle Link Elemente mit /site/example.com starten. Wie invertieren Sie den obigen Ausdruck, so dass er ** bestätigt, dass keine Link Elemente mit /site/example.com beginnen?

Ich habe versucht, den folgenden regulären Ausdruck ohne Glück: /[^(site/example\.com)].*, so dass dies nicht funktioniert:

Nicht-Arbeits Strategie 1 (Negation von einzelnen Zeichen) I Ich bin mir bewusst, dass dies wahrscheinlich für die Negierung eines einzelnen Zeichens funktionieren würde, da diese SO-Frage das macht: XML schema restriction pattern for not allowing empty strings

Die vorgeschlagene Muster in dieser Frage <xs:pattern value=".*[^\s].*" />

Aber negiert nur ein einzelnes Zeichen in diesem Fall nicht funktioniert, da es richtig scheitern würde:

/site/example.com

aber auch, es wäre falsch

/Lösungen

scheitern

Nicht-Arbeits Strategie 2 (fortgeschrittener regexp Look-Ahead) Nach dieser Frage SO (Regular expression to match a line that doesn't contain a word?), können Sie dies mit negativen Look-Ahead-(?!expr) lösen könnten.

So wird dies in gewöhnlichen regexp arbeiten:

^* $

nun leider xsd Validierungen unterstützen nur begrenzt regexps ((/ site/example.com)?!.). Laut dieser Site werden keine Lookaheads unterstützt: regular-expressions.info -- xsd

Das beschreibt ziemlich genau das, was ich bis jetzt versucht habe.

Meine Frage ist, wie negiere ich einen regulären Ausdruck in einem XSD-Schema?

Antwort

1

Sie erwähnen nicht, ob Sie an XML Schema 1.0 und XPath 1.0 gebunden sind, aber wenn nicht, ist es möglich, Ihr Ziel mit xs: assert's zu erreichen (was vielleicht etwas Arbeit erfordert) aus dem Gedächtnis ...):

<xs:element name="Link" type="xs:normalizedString" minOccurs="0"> 
    <xs:simpleType> 
    <xs:restriction base="xs:token"> 
     <xs:assert test="not(fn:starts-with($value , '/site/example.com'))" /> 
    </xs:restriction> 
    </xs:simpleType> 
</xs:element> 

Einige Links von möglichem Interesse:

http://www.ibm.com/developerworks/library/x-xml11pt2/

http://www.w3.org/TR/xpath-functions/#func-starts-with

Cheers,

+0

Vielen Dank, ich werde das prüfen müssen –

2

Das ist einfacher in XSD 1.1 zu tun, wo man Behauptungen verwenden Stellen Sie sicher, dass der Wert nicht mit der von Ihnen angegebenen Zeichenfolge beginnt. Aber konzeptionell ist es selbst in XSD 1.0 und einfachen regulären Ausdrücken einfach genug: Sie möchten sicherstellen, dass die Zeichenfolge nicht mit "/site/example.com" beginnt. Wenn es auf diese Weise tat beginnen, würden Sie eine logische Verbindung einer Reihe von Fakten über die Saite haben.

  • substring (., 1, 1) = '/'
  • substring (, 2, 1) = 's'
  • substring (., 3, 1) = 'i'
  • ...
  • substring (. 17, 1) = 'm'

Sie wollen negiere diese Verbindung von Fakten. Nach De Morgans Gesetzen ist ~ (a und b und ... und z) äquivalent zu (~ a oder ~ b oder ... oder ~ z). So können Sie tun, was Sie durch das Schreiben einer Disjunktion der folgenden Begriffe müssen:

[^/].* 
    |.([^s].*)? 
    |.{2}([^i].*)? 
    |.{3}([^t].*)? 
    |.{4}([^e].*)? 
    |.{5}([^/].*)? 
    |.{6}([^e].*)? 
    |.{7}([^x].*)? 
    |.{8}([^a].*)? 
    |.{9}([^m].*)? 
    |.{10}([^p].*)? 
    |.{11}([^l].*)? 
    |.{12}([^e].*)? 
    |.{13}([^\.].*)? 
    |.{14}([^c].*)? 
    |.{15}([^o].*)? 
    |.{16}([^m].*)? 

In jedem Begriff über dem subexpression der Form [^s].* in (...)? gewickelt wurde - der Begriff .{2}([^i].*)? jede Zeichenfolge mit zwei Zeichen beginnen ist in Ordnung, wenn das dritte Zeichen kein i ist oder wenn es kein drittes Zeichen gibt. Dies stellt sicher, dass Zeichenfolgen, die kürzer als 17 Zeichen sind, nicht ausgeschlossen werden, auch wenn sie zufällig Präfixe der verbotenen Zeichenfolge sind.

Um dies in einem XSD-Schemadokument zu verwenden, müssen Sie natürlich alle Leerzeichen entfernen, wodurch die Regex schwerer zu lesen ist.

[Zusatz, Juni 2016] Siehe auch this related and more general question.

Verwandte Themen