6

私はXMLスキーマの操作にかなり慣れていないので、これが私自身が信じているよりも些細なことである場合は、私の無能さを許してください。

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

したがって、有効な要素には次のものが含まれます。

<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のおかげで、これが私が今いる場所です。

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

繰り返し(またはなどget getpost post postと空白がない(またはなどgetpostpostputdelete)を除いて、どちらが機能しますか


編集

これを少し遊んだ後、私はアイデアを思いつきました:すべての可能なシーケンスの列挙。ありがたいことに、このリストは(当面は)4つの通常の転送方法、、、、、に固定されているので、次のように考えましたgetpostputdelete

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

これが良い考えではない理由を誰かが見ることができますか?

4

5 に答える 5

12

基本的な問題は、列挙によっても対処できます。

<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>、リスト内の各トークンが一意であることを検証できません。ただし、空白の問題には対処します(getpost拒否されます)。

于 2012-01-01T07:04:56.647 に答える
3

simpleTypeの制限として正規表現を使用できます: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>
于 2011-12-31T22:58:46.403 に答える
3

定期的にこれをいじくり回した後、私はこのパターンのハルクを思いついた。最初の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))

これはとの順列とうまく一致get post put delete headoptions、さらにそれらが正しく順序付けられている必要があります(これもちょっといいです

とにかく、要約すると:

"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メソッドであることを考えると、変更は予測できず、問題なく機能するはずです。


また、パターンを生成するためのクイックスクリプト(PHP)は次のとおりです。

$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));

()必要ないと思うので一番外側を省略しています。

于 2012-03-15T10:11:43.617 に答える
1

次のような空白を処理できます。

(get | post | put | delete)(\ sget | \ spost | \ sput | \ sdelete){0,3}

getpostとは一致しません。

于 2012-01-01T12:47:25.353 に答える
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]))*

ゼロ以上の空白と値の組み合わせが可能です。値はこの形式で与えられます

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

これは、ネガティブルックビハインド(?<![...])を使用して、テキスト内に以前に存在していないことを確認します。\b他のオプションの一部であるオプションが問題を引き起こさないことを確認するために、単語境界マーカーを使用しています。例として、オプションがあり、、、およびfoobarオプションが有効になるのを防ぐfoobarオプションが必要ない場合があります。foobarfoobar

これはXMLに組み込まれるため、スキーマに配置するときに<文字をに置き換える必要があることに注意してください。&lt;

また、最後の警告ですが、すべての正規表現プロセッサが後読み機能をサポートしているわけではありません。

于 2015-03-27T10:35:13.520 に答える