Mapping XSD to CAM
You've already seen how an XSD decimal datatype maps to CAM, but to migrate existing schemas you should understand how the other XSD datatypes get mapped.
Figure 4 shows a contrived schema that simply contains representative samples of many common XSD datatypes. These are grouped into logical chunks, separating numbers, strings, and date/time elements. You can see a full list and relationships of all datatypes in the
built-in datatypes section of the official W3C Schema specification.
 | |
| Figure 4. The DataTypeSamples Schema: This schema sandbox represents many of the XML Schema datatypes. |
In the CAM editor, create a new CAM template from the DataTypeSamples schema (you can find these in the
downloadable code in the DataTypeSamples folder,
DataTypeSamples.xsd and
DataTypeSamples.cam). To recap, the Structure view shows the placeholders generated for the datatypes while the Rules view shows the validation semantics (see
Figure 5).
 | |
| Figure 5. The DataTypeSamples CAM Template: Converting the assorted datatypes from XML Schema to CAM yields this display in the CAM editor. |
Table 1 reorganizes the information from the Structure and Rules views to be more digestible. The
Category and
Data Type columns list each datatype from the original schema (see
Figure 4) along with its category. The
Placeholder column shows how this maps to the structure portion of the CAM template, and the final two columns show the business context. As an example in interpreting this table, consider the
decimalElement (row 3) that uses the decimal datatype you saw in the earlier zip code examples. The placeholder for a decimal datatype is
%54321.00%. The business rule (
######.##) indicates that it must contain only digits with an optional leading minus sign for the integer portion of the number, followed by a decimal point, followed by precisely two digits in the fractional portion of the number. While zero and the octothorp (
#) are seemingly the most straightforward mask elements, there are some subtleties involved in knowing how they restrict your values, as you'll see next.
Table 1. Datatype Mapping: CAM generates the placeholder, condition, and business rule shown for each XML Schema data type listed. Depending on the data type, CAM generates one rule or more than one rule, and may apply a rule with a mask or a rule with a datatype, as discussed in the text.
| # |
Category |
Data Type |
Placeholder |
Condition |
Business Rule |
| 1 |
|
booleanElement |
%false% |
|
restrictValues(
'true'|'false') |
| 2 |
number |
byteElement |
%type
= byte% |
|
datatype(
byte) |
| 3 |
number |
decimalElement |
%54321.00% |
|
setNumberMask(
######.##) |
| 4 |
number |
doubleElement |
%type
= double% |
|
datatype(double) |
| 5 |
number |
floatElement |
%54321.00% |
|
setNumberMask(
######.####) |
| 6 |
number |
intElement |
%12345% |
|
setNumberMask(
######) |
| 7 |
number |
longElement |
%type
= long% |
|
datatype(long) |
| 8 |
number |
negativeIntegerElement |
%type
= negativeInteger% |
|
datatype(
negativeInteger) |
| 9 |
number |
shortElement |
%type
= short% |
|
datatype(
short) |
| 10 |
number |
unsignedIntElement |
%type
= unsignedInt% |
|
datatype(
unsignedInt) |
| 11 |
string |
stringElement |
%string% |
|
|
| 12 |
string |
tokenElement |
%Token% |
|
datatype(
token) |
| 13 |
string |
normalizedStringElement |
%string% |
|
datatype(
normalizedString) |
| 14 |
datetime |
dateElement |
%YYYY-MM-DDZ% |
string-length(.) < 11 |
setDateMask(
YYYY-MM-DD) |
| 15 |
datetime |
dateElement |
%YYYY-MM-DDZ% |
string-length(.) > 10 |
setDateMask(
YYYY-MM-DDZ) |
| 16 |
datetime |
dateTimeElement |
%YYYY-MM-DD
'T'HH:MI:SS.SZ% |
string-length(.) < 26 |
setDateMask(
YYYY-MM-DD'T'HH:MI:SSZ) |
| 17 |
datetime |
dateTimeElement |
%YYYY-MM-DD
'T'HH:MI:SS.SZ% |
string-length(.) > 25 |
setDateMask(
YYYY-MM-DD'T'HH:MI:SS.SZ) |
| 18 |
datetime |
timeElement |
%HH:MI:SS.SZ% |
string-length(.) < 13 |
setDateMask(HH:MI:SS.SSS) |
| 19 |
datetime |
timeElement |
%HH:MI:SS.SZ% |
string-length(.) > 12 |
setDateMask(HH:MI:SS.SSSZ) |
| 20 |
datetime |
durationElement |
%P1% |
|
restrictValues( 'P1'|'Y2'|'M3'|'DT1'|'H1'|'0M'|'0S') |
For now, there are several important points to glean from Table 1:
- Generated rules are illustrative, not normative. That is, there are usually several different rules you may define to achieve approximately the same thing. The CAM processor in this implementation has made certain choices—but you should consider them guidelines rather than gospel. For example, some datatypes have associated rules with masks (e.g., floatElement) while others have associated rules with the datatype predicate (e.g., doubleElement). (The datatype predicate literally indicates that the value must match that datatype as Java understands it, because CAMed is a Java application.) This CAM processor chose to create its rules in that fashion, but you could do the reverse if you wish: use something like setNumberMask(######.############) for doubleElement or datatype(float) for floatElement.
| Author's Note: My recommendation would be to use datatype() for both floats and doubles unless you want to restrict the fractional portion of the number to a specific number of digits (the next section discusses this point further). |