RELAX NG supports the description of
text nodes as lists of
whitespace-separated values using the list
pattern. This is the only pattern that transforms the structure of
the document at validation time by splitting text values into lists
of values. The benefit of doing so is that within a
list
pattern, all the patterns that constrain data
values can be combined with the compositors, which lets you constrain
the combination of these values.
If you use a list
pattern without defining
cardinality, you may not get what you expect. An attribute defined
as:
<attribute name="see-also"> <list> <data type="token"/> </list> </attribute>
or, using the compact syntax:
attribute see-also {list {token}}
doesn’t match a list of tokens (such as
see-also="0345442695
0449220230
0449214044
0061075647
0061075612
“) but rather only a list of exactly one
token (such as see-also="0345442695
“). This is
because the list
pattern splits the text value
into a list of values. This list is then evaluated against the
patterns that are included within the list
pattern. If you want a list of any number of
token
s, use a zeroOrMore
pattern to express that:
<attribute name="see-also"> <list> <zeroOrMore> <data type="token"/> </zeroOrMore> </list> </attribute>
Here’s the compact syntax:
attribute see-also {list {token*}}
This definition treats the
see-also
attribute as a list of tokens and
doesn’t add any other constraints (this result is of
course different when there are more datatypes). You can use other
compositors in the list
pattern exactly as in
other contexts. To express that, you want a list with one to four
tokens, you would write:
<attribute name="see-also"> <list> <data type="token"/> <optional> <data type="token"/> </optional> <optional> <data type="token"/> </optional> <optional> <data type="token"/> </optional> </list> </attribute>
or, using the compact syntax:
attribute see-also {list {token, token?, token?, token?}}
That is certainly verbose, but you’ve already seen there are no other options for defining the number of occurrences with RELAX NG.
You can also constrain the values of these tokens through an enumeration:
<attribute name="see-also"> <list> <oneOrMore> <choice> <value>0836217462</value> <value>0345442695</value> <value>0449220230</value> <value>0449214044</value> <value>0061075647</value> </choice> </oneOrMore> </list> </attribute>
or:
attribute see-also {list {("0836217462"|"0345442695"|"0449220230"|"0449214044"|"0061075647")+}}
A final point to note is that the list
mechanism
lets you define different constraints for different members of a
list. To illustrate this feature, let’s say you wish
to give the physical dimension of a book by giving each of its three
dimensions a unit, such as:
<book id="b0836217462" available="true" dimensions="0.38 8.99 8.50 inches">
In this case, you can define the dimensions
attribute as:
<attribute name="dimensions"> <list> <data type="token"/> <data type="token"/> <data type="token"/> <choice> <value>inches</value> <value>cm</value> <value>mm</value> </choice> </list> </attribute>
or:
attribute dimensions {list {token, token, token, ("inches"|"cm"|"mm")}}
3.14.146.180