XML模式;有效属性值列表中的倍数 [英] XML schema; multiple from a list of valid attribute values
问题描述
我刚开始使用XML模式,因此,如果这比我本人认为的琐碎小事,请原谅我的无能.
I'm reasonably new to working with XML schemas, so excuse my incompetence if this is more trivial than I myself believe it must be.
我正在尝试创建一个必需属性,该属性必须包含列表中的1个或多个用空格分隔的字符串值.该列表是4种典型的HTTP请求方法. get
,post
,put
和delete
.
I'm trying to create a required attribute that must contain 1 or more white-space-separated string values from a list. The list is the 4 typical HTTP request methods; get
, post
, put
, and delete
.
因此有效的元素应包括:
So valid elements would include:
<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" />
我尝试用枚举和长度愚弄,但是我不相信我正在理解我需要做的事情(或实际上是否可行,尽管看起来似乎应该这样做是)
I've tried fooling with enumerations and length, but I don't believe I'm understanding what I need to do (or for that matter if it is in fact possible, though it seems as though it should be)
这是我现在的位置,这要感谢@tdrury:
This is where I'm at now, thanks to @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 get
或post post post
)和缺少空白(,例如getpost
或postputdelete
)以外,其他方法都可以使用
Which works, except for repetition (such as get get
or post post post
) and absent whitespace (such as getpost
or postputdelete
)
修改:
玩了一点之后,我想到了一个主意:对所有可能的序列进行枚举.幸运的是,此列表(暂时)固定为四种常见的传输方法,分别是get
,post
,put
和delete
,因此我想出了:
After playing around with this a bit, I came up with an idea: an enumeration of all possible sequences. Thankfully, this list is (for the time being) fixed to the four usual transport methods, get
, post
, put
, and delete
, so I figured:
<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>
有人能看到一个不是是个好主意的原因吗?
Can anyone see a reason that this would not be a good idea?
推荐答案
定期解决这个问题之后,我想到了这种模式. PCRE漂亮印刷中的第一个:
After periodically screwing around with this, I came up with this hulk of a pattern; first in PCRE pretty-print:
^
(
(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
head
和options
的任何排列,进一步要求它们正确排序(也很不错 )
This will successfully match any permutation of get
post
put
delete
head
and options
, further requiring that they be correctly ordered (which is kinda nice too)
无论如何,总结:
"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方法,因此无法预见的变化,我认为它应该可以正常工作.
This pattern doesn't scale the greatest, as each new "token" needs to be included in every group, but given the problem domain is HTTP methods, change is unforeseeable and I figure it should work just fine.
此外,这是一个用于生成模式的快速脚本(PHP):
Also, here's a quick script (PHP) to generate the pattern:
$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));
它省略了最外面的()
,因为我认为这不是必需的.
It omits the outermost ()
because I don't think it's necessary.
这篇关于XML模式;有效属性值列表中的倍数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!