我是使用XML模式的新手,所以请原谅我的无能,如果这比我自己认为必须的更微不足道.
我正在尝试创建一个必需的属性,该属性必须包含一个或多个列表中以空格分隔的字符串值.该列表是4种典型的HTTP请求方法; get
,post
,put
,和delete
.
所以有效的元素包括:
<rule methods="get" />
<rule methods="get post" />
<rule methods="post put delete" />
Run Code Online (Sandbox Code Playgroud)
而无效元素包括:
<rule methods="get get" />
<rule methods="foobar post" />
<rule methods="get;post;put" />
Run Code Online (Sandbox Code Playgroud)
我试着用枚举和长度来愚弄,但我不相信我理解我需要做什么(或者如果它实际上是可能的话,尽管看起来好像应该这样)
这就是我现在所处的位置,感谢@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>
Run Code Online (Sandbox Code Playgroud)
哪个有效,除了重复(如get get
或post post post
)和缺少空格(如getpost
或postputdelete
)
编辑:
在玩了一下之后,我提出了一个想法:列举所有可能的序列.值得庆幸的是,这份名单是(暂时)固定在四个通常的运输方式,get
,post
,put
,和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>
Run Code Online (Sandbox Code Playgroud)
任何人都可以看到这不是一个好主意的原因吗?
DRH*_*DRH 10
基本问题也可以用枚举来解决:
<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>
Run Code Online (Sandbox Code Playgroud)
遗憾的是,这与<xs:pattern>
解决方案具有相同的限制,无法验证列表中的每个令牌是否唯一.然而,它确实解决了空白问题(getpost
将被拒绝).
经过定期的研究后,我想出了这个庞大的模式;首先是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)
)
$
Run Code Online (Sandbox Code Playgroud)
与 XML 兼容:
((get(\spost)?(\sput)?(\sdelete)?(\shead)?(\soptions)?)|(post(\sput)?(\sdelete)?(\shead)?(\soptions)?)|(put(\sdelete)?(\shead)?(\soptions)?)|(delete(\shead)?(\soptions)?)|(head(\soptions)?)|(options))
Run Code Online (Sandbox Code Playgroud)
这将成功匹配get
post
put
delete
head
和的任何排列options
,进一步要求它们被正确排序(这也很好)
无论如何,总结一下:
"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
Run Code Online (Sandbox Code Playgroud)
这种模式的规模并不是最大的,因为每个新的“令牌”都需要包含在每个组中,但考虑到问题域是 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));
Run Code Online (Sandbox Code Playgroud)
它省略了最外面的部分()
,因为我认为没有必要。
归档时间: |
|
查看次数: |
17990 次 |
最近记录: |