Supporting different styles of XML (a question and an answer)

Before being certain that this forum was the right place for
people learning XForms to ask questions, I sent a couple of
questions to knowledgeable individuals.  Since the question and
their answers may be of interest to others studying XForms (as
previous questions and answers here have been for me), John Boyer
has kindly given me permission to post his answers here.

My first question was:

 > Q1.  The introduction in the XForms spec illustrates the
 > principle that the cash-or-credit-card question in a form might
 > correspond to either of two XML representations, one which
 > represents the choice with an element whose PCDATA content is
 > either 'cc' or 'cash', and one which uses an attribute on the
 > parent element to hold that choice.  The spec says "Element
 > instance ... gives the author full control on the structure of
 > the submitted XML data, including namespace information."

 > Can the author choose to represent the cash/card choice as a
 > choice between an empty 'cash' element and a 'creditcard'
 > element with required attributes for type of card, number, and
 > expiration data?  That is, can one specify the instance
 > document in such a way that the XML submitted is either

 >   <purchase>
 >     <creditcard type="..." num="..." expiration="..."/>
 >   </purchase>

 > or

 >   <purchase><cash/></purchase>

 > ?

[Meta-commentary: this formulation is sub-optimal because I have
not yet done the necessary homework: that is, I have not tried to
make this XML representation or something like it work in an
XForms processor.]

[[Since sending this question, I have done some of the homework,
and can report that I did manage to make my XForm produce
structures like those shown.  Like John's solution below,
the solution I worked out has the drawback that it has a
redundant indication of the 'method' in addition to the presence
of either 'cash' or 'credit-card', but I assume that
replacing that with a variable is a simple matter of
refining the form a bit.  -cmsmcq]]

John's reply:

 > On Q1, yes you can get XForms to make a choice in the schema
 > instance sent back to the server.  The easiest way to do this
 > is perhaps a little irritating from the schema purist's
 > perspective because it highlights the difference between a
 > schema instance completed versus a schema instance in progress.
 > Here's a chunk of XForms that handles the purchase type example
 > you asked about below:

 > <xf:model>
 >    <xf:instance xmlns="">
 >       <purchase>
 >          ...
 >          <method>cash</method>
 >          <creditcard type="..." num="..." expiration="..."/>
 >          <cash ... />
 >       </purchase>
 >    </xf:instance>
 >    ...
 >    <xf:bind nodeset="cash" relevant="../method='cash'"/>
 >    <xf:bind nodeset="creditcard" relevant="../method != 'cash'"/>
 >    ...
 >    <!-- By default, non-relevant nodes are omitted from the  
submission data, so
 >         only one of cash and creditcard elements will be submitted  
-->
 >    <xf:submission id="X" resource="http://example.com/ 
purchaseServlet" ... />
 > </xf:model>

 > <xf:select1 ref="method">
 >    <xf:label>Payment method: </xf:label>
 >    <xf:item>
 >       <xf:label>Cash on Delivery</xf:label>
 >       <xf:value>cash</xf:value>
 >    </xf:item>
 >    <xf:item>
 >       <xf:label>Credit Card</xf:label>
 >       <xf:value>creditcard</xf:value>
 >    </xf:item>
 > </xf:select1>

 > <!-- This group only shows if the "creditcard" data node is  
relevant -->
 > <xf:group ref="creditcard">
 >     <!-- form controls for collecting credit card details -->
 > </xf:group>

 > <!-- This group only shows if the "cash" data node is relevant -->
 > <xf:group ref="cash">

 >     <!-- form controls for collecting cash-on-delivery details,
 >          if any (such as customer account number) -->
 >     <!-- You wouldn't need this group if you had no further
 >          details to collect though -->

 > </xf:group>

 > <xf:submit submission="X">
 >    <xf:label>Submit Purchase</xf:label>
 > </xf:submit>

 > In the above example, based on user choice of a payment method,
 > either the cash or creditcard will become non-relevant and be
 > omitted from the submission.  Both elements are needed in the
 > instance data to allow UI bindings to collect information about
 > the credit card or COD transaction, and we don't know
 > beforehand which will be selected by the user.

 > However, suppose your schema says you can only have one of the
 > elements but not both.  There are several solutions.  The
 > easiest is to harken back to your XML 2005 talk on how schema
 > validation is different from being married, in which you talked
 > about using different schemas for different purposes.  One can
 > provide a different schema for the XForms fill experience than
 > is used for validation preprocessing of the server-side
 > business transaction.

 > Unfortunately, some people don't want to do this, in which case
 > there are solutions that can be created in XForms in which the
 > schema instance is always structurally valid according to the
 > final transaction schema, but it's more work involving the use
 > of insert and delete actions parallel to the user selection of
 > structure, e.g. the choice of payment method.

Thank you, John!

-- 
****************************************************************
* C. M. Sperberg-McQueen, Black Mesa Technologies LLC
* http://www.blackmesatech.com
* http://cmsmcq.com/mib
* http://balisage.net
****************************************************************

Received on Tuesday, 4 August 2009 00:46:28 UTC