你有几个选择。
(1) 您可以通过编写一个相当复杂的正则表达式来强制执行您描述的约束,如下所示:
- 存在所有四个字符串的每个合法值都是序列(“HASCALCULATOR”、“READ ONLY”、“LISTUPDATENEEDED”、“MANDATORY”)的一些排列的串联。
- 每个存在少于四个字符串的合法值都是一些排列连接的前缀。
因此,您可以通过计算四个字符串的 24 次排列,并将后缀设为可选来完整地写出正则表达式:
<xs:simpleType name="properties">
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse"/>
<xs:pattern value="((HASCALCULATOR (LISTUPDATENEEDED
(READ ONLY (MANDATORY)?)?)?)|(HASCALCULATOR
(LISTUPDATENEEDED (MANDATORY (READ ONLY)?)?)?)|(HASCALCULATOR
(READ ONLY (LISTUPDATENEEDED (MANDATORY)?)?)?)|(HASCALCULATOR
(READ ONLY (MANDATORY (LISTUPDATENEEDED)?)?)?)|(HASCALCULATOR
(MANDATORY (LISTUPDATENEEDED (READ ONLY)?)?)?)|(HASCALCULATOR
(MANDATORY (READ ONLY
(LISTUPDATENEEDED)?)?)?)|(LISTUPDATENEEDED (HASCALCULATOR
(READ ONLY (MANDATORY)?)?)?)|(LISTUPDATENEEDED (HASCALCULATOR
(MANDATORY (READ ONLY)?)?)?)|(LISTUPDATENEEDED (READ ONLY
(HASCALCULATOR (MANDATORY)?)?)?)|(LISTUPDATENEEDED (READ ONLY
(MANDATORY (HASCALCULATOR)?)?)?)|(LISTUPDATENEEDED (MANDATORY
(HASCALCULATOR (READ ONLY)?)?)?)|(LISTUPDATENEEDED (MANDATORY
(READ ONLY (HASCALCULATOR)?)?)?)|(READ ONLY (HASCALCULATOR
(LISTUPDATENEEDED (MANDATORY)?)?)?)|(READ ONLY (HASCALCULATOR
(MANDATORY (LISTUPDATENEEDED)?)?)?)|(READ ONLY
(LISTUPDATENEEDED (HASCALCULATOR (MANDATORY)?)?)?)|(READ ONLY
(LISTUPDATENEEDED (MANDATORY (HASCALCULATOR)?)?)?)|(READ ONLY
(MANDATORY (HASCALCULATOR (LISTUPDATENEEDED)?)?)?)|(READ ONLY
(MANDATORY (LISTUPDATENEEDED (HASCALCULATOR)?)?)?)|(MANDATORY
(HASCALCULATOR (LISTUPDATENEEDED (READ ONLY)?)?)?)|(MANDATORY
(HASCALCULATOR (READ ONLY (LISTUPDATENEEDED)?)?)?)|(MANDATORY
(LISTUPDATENEEDED (HASCALCULATOR (READ ONLY)?)?)?)|(MANDATORY
(LISTUPDATENEEDED (READ ONLY (HASCALCULATOR)?)?)?)|(MANDATORY
(READ ONLY (HASCALCULATOR (LISTUPDATENEEDED)?)?)?)|(MANDATORY
(READ ONLY (LISTUPDATENEEDED (HASCALCULATOR)?)?)?))?">
<xs:annotation>
<xs:documentation>
The pattern here was calculated this way.
1 Let A = "HASCALCULATOR", B = "LISTUPDATENEEDED",
C = "READ ONLY", and D = "MANDATORY".
2 Calculate the permutations of the sequence (A,B,C,D).
A sequence with four members has 4! = 24 permutations:
(A,B,C,D), (A,B,D,C), (A,C,B,D), (A,C,D,B), ...
3 From each permutation generate a regex of the form
(s1 (s2 (s3 (s4)?)?)?)
4 Join all of these in single optional choice.
</xs:documentation>
</xs:annotation>
</xs:pattern>
</xs:restriction>
</xs:simpleType>
(2) 通过左分解析取可以产生一个不太冗长的版本,这样一个结构就像
(A (B, (C, (D)?)?)?)
|(A (B, (D, (C)?)?)?)
|(A (C, (B, (D)?)?)?)
|(A (C, (D, (B)?)?)?)
变成类似的东西
(A ((B ((C D?)|(D C?))?
| (C ((B D?)|(D B?))?)
| (D ((B C?)|(C B?))?)))
(3) 你可以重新思考材料的表现形式。例如,您可以将四个字符串中的任何一个字符串的存在视为一个标志并忽略重复;这将使您绘制的图案可以正常工作。
(4) 您可以将标志表示为四个布尔属性,以便代替
<xs:element name="properties" type="tns:properties"/>
<!--* assumes the declaration for 'properties' type
* given above *-->
你写这样的东西:
<xs:element name="properties">
<xs:complexType>
<xs:attribute name="has-calculator" type="xs:boolean"/>
<xs:attribute name="mandatory" type="xs:boolean"/>
<xs:attribute name="read-only" type="xs:boolean"/>
<xs:attribute name="list-update-needed" type="xs:boolean"/>
</xs:complexType>
</xs:element>
(5) 您可以将标志表示为空元素,它们通过发生来表示属性:
<xs:complexType name="empty">
<xs:sequence/>
</xs:complexType>
<xs:element name="properties">
<xs:complexType>
<xs:all>
<xs:element name="has-calculator"
type="tns:empty" minOccurs="0"/>
<xs:element name="mandatory"
type="tns:empty" minOccurs="0"/>
<xs:element name="read-only"
type="tns:empty" minOccurs="0"/>
<xs:element name="list-update-needed"
type="tns:empty" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
我自己倾向于使用选项(5)。但是从问题的一般感觉,再加上全大写字符串,我猜您正在处理来自完善系统的输出,并且更改格式是不可行的。