RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Taking XML Validation to the Next Level: Introducing CAM : Page 2

The generic-sounding Content Assembly Mechanism, or CAM, is actually an exciting step forward from XML Schema, but it's new, and not well documented. This article series represents CAM: The Missing Manual.


Introduction to the CAM Editor

From this link to download the latest CAM editor, select Download in the left-hand panel, and you get a choice of downloading the CAM template editor or the JCam engine. For the bulk of this article you need only the CAM template editor (the JCam engine performs CAM validation programmatically).

To get started with the CAM editor, you may create a template from scratch, from an existing XML file, or from an existing schema (XSD) file. You'll find the ease of creating a CAM template is exactly the reverse order; that is, you gain the most leverage from an XSD file, some from an XML file, and of course none when starting from scratch. So to get started, use the canonical Purchase Order schema from the W3C. Store this file locally as po.xsd. In the editor, select File → New Template from Schema…, and supply the directory and file name where you stored the file separately (see Figure 2). The application freezes for a few seconds while it processes the file; when it comes back it fills out the Root Element field.

Figure 2. New Template From Schema Dialog: Select the directory and file name pointing to your XSD file, then select the root element from that schema to have the CAM editor generate a base CAM template for you.

The comment element is simply the name of the first node (in alphabetical order) among all <xsd:element> nodes in the po.xsd file. This file happens to contain two such nodes, comment and purchaseOrder, shown in bold in the schema excerpt below (you can see the full schema in Listing 1).

   <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <xsd:documentation xml:lang="en">
        Purchase order schema for Example.com.
        Copyright 2000 Example.com. All rights reserved.
     <xsd:element name="purchaseOrder" 
     <xsd:element name="comment" type="xsd:string"/>
     <xsd:complexType name="PurchaseOrderType">
         <xsd:element name="shipTo" type="USAddress"/>
         <xsd:element name="billTo" type="USAddress"/>
         <xsd:element ref="comment" minOccurs="0"/>
         <xsd:element name="items"  type="Items"/>
       <xsd:attribute name="orderDate" type="xsd:date"/>

You actually want the purchaseOrder element as the root, so switch the Root Element in the dialog to purchaseOrder, and then click OK to generate the template. The application prompts you (well, forces you) to save the template before proceeding. After doing that, the template opens in the CAM Template Editor (see Figure 3).

Figure 3. The CAM Editor: After generating a template from the po.xsd schema, the editor shows both a Structure a Rules view. The labels explain the iconic and textual conventions of the Structure view.

Each tabbed container in the editor is referred to as a view. The Structure view shows the tree-structured hierarchy of the XML. Figure 3 shows that a purchase order has an orderData attribute along with four child nodes: shipTo, billTo, comment, and items. The items node may contain multiple item child nodes. The CAM editor closely mirrors the underlying XML CAM template file (PurchaseOrder/purchaseOrder_from_schema.cam). As shown below, the <as:AssemblyStructure> section in the file shows virtually the same information line by line as the Structure view in Figure 3:

       <as:Structure taxonomy="XML" ID="purchaseOrder" reference="">
         <purchaseOrder orderDate="%YYYY-MM-DDZ%">
           <shipTo country="US">
           <billTo country="US">
             <item partNum="%string%">

That is partly because the CAM file maintains a clean separation between form (<as:AssemblyStructure>) and function (<as:BusinessUseContext>). In contrast, XSD files intermingle structure with the business rules (thus incurring higher maintenance costs). Here's the top-level skeleton of a complete CAM file, showing the two main elements:

     <as:Header />
     <as:AssemblyStructure />
     <as:BusinessUseContext />

You can see the complete CAM template file in Listing 2.

The Rules view (highlighted in Figure 3) shows all the business rules comprising the semantics of the template. Unlike structure, rules are stored differently in the file than in the Rules view. Table 2 reproduces the rules as shown in the Rules view for a close-up look. Without going into all the details of these rules, what you can glean from them is:

  • Rules may be conditional or absolute. For example, the orderDate format requirement changes depending on its length.
  • Items and conditions are specified via XPath. XPath is used extensively in CAM, providing tremendous flexibility and resolution. XML Schema 1.0, by contrast, uses XPath only for the advanced xs:unique and xs:key concepts.
  • Rules may apply to as broad or as narrow a range of elements as you need. By its very nature, XPath supports selection of whatever part of a document you need: one element, one attribute, all elements of a given name, all elements in a certain position in the tree, etc.
  • Rules are compact, concise, and intuitive. In fact, as you'll see, writing CAM rules is practically the same thing as writing your application requirements.
Table 2. Business Rules in the Editor: Converting the XML Schema for the purchase order to CAM automatically generates these rules, which serve as a starting point.
Condition Item Action
  //purchaseOrder/@orderDate makeOptional()
string-length(.) < 11 //purchaseOrder/@orderDate setDateMask(YYYY-MM-DD)
string-length(.) > 10 //purchaseOrder/@orderDate setDateMask(YYYY-MM-DDZ)
  //shipTo/@country makeOptional()
  //shipTo/@country datatype(NMTOKEN)
  //shipTo/zip setNumberMask(######.##)
  //billTo/@country makeOptional()
  //billTo/@country datatype(NMTOKEN)
  //billTo/zip setNumberMask(######.##)
  //purchaseOrder/comment makeOptional()
  //items/item makeRepeatable()
  //items/item makeOptional()
  //item/quantity setNumberMask(######)
  //item/quantity setNumberRange(1-999999)
  //item/USPrice setNumberMask(######.##)
  //item/comment makeOptional()
  //item/shipDate makeOptional()
string-length(.) < 11 //item/shipDate setDateMask(YYYY-MM-DD)
string-length(.) > 10 //item/shipDate setDateMask(YYYY-MM-DDZ)

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date