W3C home > Mailing lists > Public > www-forms@w3.org > April 2005

RE: WXS types in XForms

From: Mark Birbeck <mark.birbeck@x-port.net>
Date: Fri, 8 Apr 2005 12:34:36 +0100
Message-ID: <B1FDDDDE-541C-43FD-B42D-BD1F5ED31434@S009>
To: "'Victor Engmark'" <victor.engmark@cern.ch>
Cc: <www-forms@w3.org>, <ava@vaz.ru>

Victor,

> I believe the problem arises from null (the empty string) not 
> being a valid number. The same goes for dates, and I've used 
> the following solution:
>   <simpleType name="null_date">
>     <union>
>       <simpleType>
>         <restriction base="date">
>         </restriction>
>       </simpleType>
>       <simpleType>
>         <annotation>
>           <documentation>The empty string</documentation>
>         </annotation>
>         <restriction base="string">
>           <length value="0"/>
>         </restriction>
>       </simpleType>
>     </union>
>   </simpleType>

You're right in describing the problem, but XML Schema provides a better
solution that saves you having to create lots of new data types with unions
in -- it's the concept of 'nillable'. This allows an element that is empty
to be classed as valid, even if its schema type does not allow this.

To indicate that your element can be set to nil, you use xsd:nillable [1] in
the schema definition. Note however that this is an attribute of
xsd:element, not the type, so Alexander's example would need to become:

  <xsd:element name="some-elem" type="myType" nillable="true" />

  <xsd:simpleType name="myType">
    <xsd:restriction base="xsd:decimal">
      <xsd:minInclusive value="0" />
      <xsd:fractionDigits value="5" />
    </xsd:restriction>
  </xsd:simpleType>

Although this might seem inconvenient, it is more logical. If you take your
example, you have effectively invented a new data type that is an amalgam of
a date and nothing. My guess is that this doesn't really reflect your data
structure. What you most likely have is an *element* that can either take a
date, or be left empty. The XML Schema syntax reflects this. (It also allows
you to use other people's data types without having to create new types all
the time.)

Once you have the schema set up, then to make use of it you use @xsi:nil [2]
on your element:

  <some-elem xsi:nil="true" />

Note that you can manipulate this attribute in your instance data just like
any other, so it's pretty easy for example, to link it to a 'checkbox' which
indicates whether the element is 'nil' or not. Your form might ask a user
for their travel dates, and using @xsi:nil you could indicate that an empty
return date means in effect that the user only wants a single ticket.
@xsi:nil allows the return date to be valid if empty (see Example 1).

Another technique you might consider is that instead of letting the user
'choose' to have a nil value, you work the other way around -- use a
calculation to automatically set the nil attribute to 'true' if the element
itself is left empty (see Example 2).

= Example 1 =

  <xf:model>
    <xf:instance id="my-order">
      <order xmlns=""
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <travel-date>2005-05-07</travel-date>
        <return-date xsi:nil="false">2005-05-07</return-date>
      </order>
    </xf:instance>

    <xf:bind nodeset="travel-date" type="xsd:date" />

    <xf:bind nodeset="return-date" type="xsd:date"
        relevant="boolean-from-string(@xsi:nil)=true()">
      <xf:bind nodeset="@xsi:nil" type="xsd:boolean" />
    </xf:bind>
  </xf:model>

  <style>
    .disabled, ::disabled {display: none; }
  </style>

  <xf:input ref="travel-date">
    <xf:label>Return Date:</xf:label>
  </xf:input>

  <xf:input ref="return-date/@xsi:nil">
    <xf:label>Return trip?</xf:label>
  </xf:input>

  <xf:input ref="return-date">
    <xf:label>Return Date:</xf:label>
  </xf:input>


= Example 2 =

  <xf:model>
    <xf:instance id="my-order">
      <order xmlns=""
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <children xsi:nil="true"
          xsi:type="xsd:nonNegativeInteger">0</children>
      </order>
    </xf:instance>

    <xf:bind nodeset="children/@xsi:nil" calculate=".. = ''" />

    <xf:bind nodeset="return-date" type="xsd:date"
      relevant="boolean-from-string(@xsi:nil)=true()" />
  </xf:model>

Regards,

Mark

[1]
<http://www.w3.org/TR/xmlschema-1/structures.html#Element_Declaration_detail
s>
[2] <http://www.w3.org/TR/xmlschema-1/structures.html#xsi_nil>


Mark Birbeck
CEO
x-port.net Ltd.

e: Mark.Birbeck@x-port.net
t: +44 (0) 20 7689 9232
w: http://www.formsPlayer.com/
b: http://internet-apps.blogspot.com/

Download our XForms processor from
http://www.formsPlayer.com/
Received on Friday, 8 April 2005 11:34:53 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Saturday, 10 March 2012 06:22:00 GMT