У вас есть несколько вариантов.
(1) Вы можете следить за соблюдением ограничений вы описали, написав довольно сложное регулярное выражение, по следующим направлениям:
- Каждое юридическое значение со всех четырех строк, присутствующих является объединением некоторой перестановки («HASCALCULATOR», «READ ONLY», «LISTUPDATENEEDEDED», «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) сам. Но из общего чувства вопроса, в сочетании со строками all-caps, я думаю, вы имеете дело с результатами из хорошо зарекомендовавшей себя системы, и изменение формата не представляется возможным.