2012-03-27 27 views
0

XSDで文字列の内容の検証を行います。具体的には、私は、特定の文字列が発生しないを検証したい一致する文字列を無効にするXSD制限

このルールを検討すると、自分の文字列が存在することを確認できます。すべてLinkの要素を探して、この特定の文字列で始まる:/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>     

言い換えれば、上式は、すべての要素がLink/site/example.comで始まることを確認します。上記の式をどのように逆にして、Linkの要素が/site/example.comで始まらないことを確認しますか?

私は運では、次の正規表現を試してみました:/[^(site/example\.com)].*ので、これが動作しない:

を、働いていない戦略1(単一の文字の否定) Iこれはおそらく単一の文字を否定するために働くことになることを認識しています。これは次のことです。XML schema restriction pattern for not allowing empty strings

その質問<xs:pattern value=".*[^\s].*" />

しかし、それは正確に失敗するので、単一の文字が、このケースでは動作しませんのみを否定で推奨パターン:

/site/example.com

また、間違って失敗する可能性があります。

/solutions

、働いていない戦略2(高度な正規表現先読み) このSO質問(Regular expression to match a line that doesn't contain a word?)によると、あなたは否定先読み(?!expr)でこれを解決することができます。

だから、これは通常の正規表現で動作します:(?!。(/サイト/ example.com))

^* $

さて、残念ながらXSDの検証は、限られた正規表現をサポートしています。このサイトによれば、先読みはサポートされていません:regular-expressions.info -- xsd

これは私が今まで何を試したかをほとんど説明しています。

私の質問は、XSDスキーマで正規表現を否定するにはどうすればいいですか?

答えて

1

XMLスキーマ1.0とXPath 1.0にバインドされているかどうかは言いませんが、そうでない場合は、xs:assertの目的に沿ってこの行に沿って達成することができます。メモリから):

<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> 

可能な関心のいくつかのリンク:

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

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

乾杯、

+0

ありがとう、私はこれを調べなければならないでしょう –

2

これは、あなたがするアサーションを使用することができますXSD 1.1、で行う方が簡単です値が指定した文字列で始まらないようにしてください。概念的に言えば、XSD 1.0やシンプルな正規表現であっても、文字列が "/site/example.com"で始まらないようにする必要があります。それはそのように始まった場合は、文字列についての事実の一連の論理積があるだろう:(。、1、1)

  • 部分文字列を= '/'
  • ストリング(、2、。 1)= 'S'
  • ストリング(。、3、1)= 'I'
  • ...
  • ストリング(17、1)= 'M'

あなたがしたいですこの事実を否定する。 De Morganの法則では、〜(aとb、...とz)は(〜aまたは〜bまたは...〜z)と等価です。だから、次の用語の論理和を書き込むことによって、あなたが必要なものを行うことができます:フォーム[^s].*の部分式上記各項で

[^/].* 
    |.([^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].*)? 

(...)?に包まれてきた - 用語.{2}([^i].*)?は、2つの文字で始まる任意の文字列を意味し、 3番目の文字がiでない場合、または3番目の文字がまったくない場合はOKです。これにより、長さが17文字より短い文字列は、たとえそれらが禁則文字列の接頭辞であっても除外されません。

もちろん、これをXSDスキーマ文書で使用するには、すべての空白を削除する必要があります。これにより、正規表現が読みにくくなります。

[追加、June 2016] this related and more general questionも参照してください。

関連する問題