2011-12-31 15 views
4

私はXMLスキーマを扱うのが慣れているので、私の無能さを許してください。XMLスキーマ。有効な属性値のリストから倍数

リストから1つ以上の空白で区切られた文字列値を含む必要がある属性を作成しようとしています。このリストは、典型的な4つのHTTP要求メソッドです。 get,post,putおよびdeleteである。

ので、有効な要素が含まれます:

<rule methods="get" /> 
<rule methods="get post" /> 
<rule methods="post put delete" /> 

を無効の要素が含まれるのに対し:

<rule methods="get get" /> 
<rule methods="foobar post" /> 
<rule methods="get;post;put" /> 

を私が列挙し、長さをだまししようとしましたが、私は、私は理解してるとは思いません何をする必要があるのですか(、実際に可能ならばそれは問題ありませんが、それはである必要があります)


これは私が今ではだところ、おかげで@tdruryすることです:反復(などget getとして、あるいはpost post post)および不在の空白(などgetpostpostputdeleteなどを除き、作品

<xs:attribute name="methods" use="required"> 
    <xs:simpleType> 
     <xs:restriction base="xs:string"> 
      <xs:whiteSpace value="collapse" /> 
      <xs:pattern value="(?:(?:get|post|put|delete)\s?){1,4}" /> 
     </xs:restriction> 
    </xs:simpleType> 
</xs:attribute> 


編集

これをちょっと試してみた後、考えられるすべてのシーケンスを列挙したアイデアを思いつきました。ありがたいことに、このリストは4つの通常の輸送方法、getpostput、およびdeleteに固定(を当面)であるので、私は考え出し:

<xs:restriction base="xs:string"> 
    <xs:whiteSpace value="collapse" /> 
    <xs:enumeration value="delete" /> 
    <xs:enumeration value="put" /> 
    <xs:enumeration value="put delete" /> 
    <xs:enumeration value="post" /> 
    <xs:enumeration value="post delete" /> 
    <xs:enumeration value="post put" /> 
    <xs:enumeration value="post put delete" /> 
    <xs:enumeration value="get" /> 
    <xs:enumeration value="get delete" /> 
    <xs:enumeration value="get put" /> 
    <xs:enumeration value="get put delete" /> 
    <xs:enumeration value="get post" /> 
    <xs:enumeration value="get post delete" /> 
    <xs:enumeration value="get post put" /> 
    <xs:enumeration value="get post put delete" /> 
</xs:restriction> 

は、誰もがその理由を見ることができ、これはをすることをはいいアイデアでしょうか?

あなたは単純に制限として正規表現を使用することができます

答えて

2

これを定期的に使いこなした後、私はパターンのこの荒れ果てを思いつきました。最初のPCREプリティプリントに:

^ 
(
    (get  (\s post)? (\s put)?  (\s delete)? (\s head)? (\s options)?) 
| (post (\s put)?  (\s delete)? (\s head)? (\s options)?) 
| (put  (\s delete)? (\s head)? (\s options)?) 
| (delete (\s head)? (\s options)?) 
| (head (\s options)?) 
| (options) 
) 
$ 

そしてXML互換性:

((get(\spost)?(\sput)?(\sdelete)?(\shead)?(\soptions)?)|(post(\sput)?(\sdelete)?(\shead)?(\soptions)?)|(put(\sdelete)?(\shead)?(\soptions)?)|(delete(\shead)?(\soptions)?)|(head(\soptions)?)|(options)) 

これが成功し、さらにそれらが正しく注文されることを必要、getpostputdeleteheadoptionsの任意の順列と一致します(ましたちょっといいですよ

とにかく、要約:

"get post put delete head options" // match 

"get put delete options"   // match 

"get get post put"     // fail; double get 

"get foo post put"     // fail; invalid token, foo 

"post delete"      // match 

"options get"      // fail; ordering 

それぞれの新しい「トークン」は、すべてのグループに含まれる必要があるとして、このパターンは、最大のスケールしませんが、問題のドメインがHTTPメソッドで与えられ、変更が予測不可能であり、私はそれだけで正常に動作する必要があります理解。私はそれが必要だとは思わないので、それは最も外側の()を省略

$tokens = ['get', 'post', 'put', 'delete', 'head', 'options']; 

echo implode('|', array_map(function ($token) use (&$tokens) { 
    return sprintf('(%s%s)', array_shift($tokens), 
     implode(null, array_map(function ($token) { 
      return sprintf('(\s%s)?', $token); 
     }, $tokens))); 
}, $tokens)); 


はまた、ここにパターンを生成するために迅速なスクリプト(PHP)です。

3

http://www.w3.org/TR/xmlschema-2/#dt-pattern

私は正規表現専門家ではないが、このようなものになるだろう:

<xs:attribute name="methods" use="required"> 
    <xs:simpleType> 
     <xs:restriction base="xs:string"> 
     <xs:pattern value='((get|post|put|delete)[/s]*){4}'/> 
     </xs:restriction> 
    </xs:simpleType> 
</xs:attribute> 
+0

ありがとう@それは近いですが、 'get?(get:post | put | delete)\ s?){1,4}' 'get get 'や' getpost'などがあります。重複を無効にする方法はありません。 – Dan

9

基本的な問題がで対処することができます同様に列挙:

<xs:attribute name="methods" use="required"> 
    <xs:simpleType> 
     <xs:restriction> 
      <xs:simpleType> 
       <xs:list> 
        <xs:simpleType> 
         <xs:restriction base="xs:token"> 
          <xs:enumeration value="get"/> 
          <xs:enumeration value="post"/> 
          <xs:enumeration value="put"/> 
          <xs:enumeration value="delete"/> 
         </xs:restriction> 
        </xs:simpleType> 
       </xs:list> 
      </xs:simpleType> 
      <xs:minLength value="1"/> 
     </xs:restriction> 
    </xs:simpleType> 
</xs:attribute> 

これは残念ながら<xs:pattern>溶液と同じ制限を持っており、その電子を検証することができませんリスト内のachトークンは一意です。しかし、空白の問題に対処しています(getpostは拒否されます)。あなたはこのような空白を扱うことができ

1

(取得|入れ| |投稿を削除)(\ SGET | \ spost | \ SPUT | \ sdelete){0,3}

それはないでしょうマッチgetpost。

0

私はあなたが望むものに似たものが必要でしたが、私は命令を強制することを望んでいませんでした。可能な値が追加されたときにパターンが指数関数的に増加しないようにしました。例として、あなたの列挙を使用し

、私が作ってみたパターンは、このように書きます:

(?:get|post|put|delete|head|options)(?:\s(?:(?<!.*\bget\b.*)get| 
(?<!.*\bpost\b.*)post|(?<!.*\bput\b.*)put|(?<!.*\bdelete\b.*)delete| 
(?<!.*\bhead\b.*)head|(?<!.*\boptions\b.*)options))* 

この部分

(?:[values]) 

単純に1つ以上のオプションが選択されている必要があります。いかなる値も許されていない場合、これを式全体を囲む:

(?:\s(?:[values-with-restraints]))* 

は0個以上の空白プラス値の組合せを可能にする(?:[...])?

余り。値は、この形式が既にテキストには、以前に存在していないことを確認するために、負のルック背後(?<![...])を使用しています

(?<!.*\b[value]\b.*)[value] 

に記載されています。単語境界マーカー\bを使用して、他のオプションに含まれているオプションが問題を起こさないようにします。たとえば、foobar、およびfoobarのオプションがある場合は、foobarオプションを使用してfoobarのオプションが有効にならないようにします。

これはXMLになるため、スキーマに入れたときにの文字を&lt;に置き換える必要があります。

また、すべての正規表現プロセッサがルックバック機能をサポートしているわけではありません。

関連する問題