凌枫佳境
风霜凌绝顶,红枫绚佳境
OPS XForms 参考
1. 前言
Orbeon PresentationServer (OPS)的表单处理能力基于XForms及XForms 1.0 W3C 建议. 本文介绍了XForms的一些概念和说明如何在OPS系统中使用XForms.
题注
考虑到Xforms工作还在进展,这里只涵盖了和OPS相关的XForms特性,详细信息请参考

    * XForms 1.0 (second edition) W3C Proposed Edited Recommendation
    * XForms Essentials, by Micah Dubinko (also at Amazon).
    * XForms: XML Powered Web Forms, by T. V. Raman (also at Amazon).

2. XForms概述
2.1. XForms的发展
XForms 1.0是在HTML表单的基础上设计而来。在2003年作为W3C的工作建议,并于2005年10月发布了第二版的规格说明.虽然在2005年11月Mozillia开发了相应的插件,但是主要的浏览器(Internet Explorer, Mozilla / Firefox, Opera, Safari)仍然不支持原生的XForms格式. 但是OPS通过使用服务端XForms引擎提供了转换为HTML的功能.

如果要更详细的了解服务端XForms机制请阅读: Are Server-Side XForms Engines the Future of XForms? (新版).
2.2. 优势

相对HTML表单而言,XForms提供了更好的方法去设计表单。减少了编程量(脚本和服务端的开发量),更容易创建和修改. 下面是详细说明:

   1. 使用XML表现表单. XForms 详细的定义了表单的结构和数据格式:存储在XML文档中,称为XForms实例,初始化为空,如下一个信用卡数据采集:

 <credit-card>  
<type/>  
<number/>  
<expiration-month/>  
<expiration-year/>  
</credit-card>
用户填写后的结果如下:
 <credit-card>  
<type>visa</type>  
<number>1234567812345678</number>  
<expiration-month>8</expiration-month>  
<expiration-year>2008</expiration-year>  
</credit-card>
其他程序可以对对上面的数据进行处理(例如检查信用卡是否有效)而不需要写代码来解析HTTP的协议.

   2. 声明式的约束和验证

往往数据在提交的时候需要确定是否正确,例如卡号必须是16位,月份必须是1到12,通常的做法是写代码来完成,但是使用XForms仅仅需要声明就可以了:

  <xforms:bind nodeset="/credit-card/expiration-month" type="xs:integer" constraint=". >= 1 and 12 >= ."/>
当用户录入的月份不是在1到12之间时,回弹出错误的信息,而无需书写验证的代码,后面我们还会详细介绍。

   3. 声明式的事件触发.
         1. 用户界面上需要相应用户的操作例如鼠标按下,字符的录入。在通常的开发中,通过JavaScript脚本并注册来完成事件的相应。在XForms中,预定义了大量事件处理器,而无需理解复杂的语法,例如对XForms示例设置值的事件

  <xforms:setvalue ref="/credit-card/expiration-month">11</xforms:setvalue>
一旦掌握了这些内置的简单的事件处理器,可以通过组合完成对复杂操作的处理。
3. OPS XForms Engine入门
3.1. XForms SandBox
开始使用XForms的最简单的方法是使用OPS XForms Sandbox.通过提交一个XForms文件来浏览:

    * 在线方式
    * 本地方式:如果服务器安装了OPS.使用http://localhost:8080/ops/goto-example/xforms-sandbox

提交一个XHTML + XForms 文件, 回显示结果表单或错误.
4. XForms 1.0编程
4.1. XForms 模型
4.1.1. 概述
首先我们使用XForms开发一个信息卡认证表单,这个例子显示一个简单的表单要求用户录入信用卡帐号和相关信息,如果用户录入不正确,提示信息显示在右侧,如果是错误则显示红色.
首先,表单的信息存储在称为XForms示例的XML文档中,使用xforms:instance来定义:
  <xforms:instance id="credit-card-instance">  
<credit-card>  
<type/>  
<number/>  
<expiration-month/>  
<expiration-year/>  
<verification-code/>  
<valid/>  
</credit-card>  
</xforms:instance>
XForms实例初始化并非必须为空,可以包括初始值,这里我们设置Valid元素为false:
  <xforms:instance id="credit-card-instance">  
<credit-card>  
<type/>  
<number/>  
<expiration-month/>  
<expiration-year/>  
<verification-code/>  
<valid>false</valid>  
</credit-card>
</xforms:instance>
XForms 模型必须包括一个或多个XForms实例

   1. 声明一个或多个XForms实例
   2. (可选)在XForms实例上声明的一系列规则.
   3. (可选)声明提交.

XForms实例至少包括下面:
  <xforms:model id="main-model">  
<xforms:instance id="credit-card-instance">  
<credit-card>  
<type/>  
<number/>  
<expiration-month/>  
<expiration-year/>  
<verification-code/>  
<valid>false</valid>  
</credit-card>  
</xforms:instance>  
</xforms:model>
这个实例中包括一个可选的ID属性.如果只有一个模型和一个实例这个ID是可选的,但是如果超过一个模型或实例这个属性会非常有用.
4.1.2. Model Item Properties
XForms模型可以声明一组规则,例如来实现如下:

   1. 验证信用卡号是数字并且有效
   2. 验证过期月份是有效的(整数1到12)
   3. 验证到期的年份是有效的(4位数字)
   4. 如果是Visa或MasterCard显示 "确认代码“行。
   5. 验证确认码仅当是Visa或MasterCard时。

在 XForms 模型描述这些规则使用 <xforms:bind>元素. 规则应用到XForms实例的结点和属性中.可以使用XPath来指定应用这些规则的结点或属性的. In addition to the nodeset attribute you want to have at least one attribute specifying the essence of the rule. 我们会在后面说明所有的可能的属性,现在看以下如何在信用卡表单中定义规则:

   1. 定义信用卡号必须是数字:

  <xforms:bind nodeset="number" type="xs:integer"/>

Type属性的值是W3C XML Schema的简单类型.详细定义在XML Schema primer.如果用户录入的不是整数,在录入框右边会显示错误信息.

   2. 使用XPath表达式来定义结点或属性的规则,例如定义过期时间月份必须是1到12 的整数:

  <xforms:bind nodeset="expiration-month" constraint=". castable as xs:integer and . >= 1 and 12 >= ."/>

   3. 简单的检查到期的年必须是四位数字:

  <xforms:bind nodeset="expiration-year" constraint=". castable as xs:integer and string-length(.) = 4"/>

   4. 如果是美国运通的卡则隐藏校验码字段框:

  <xforms:bind nodeset="verification-code" relevant="../type = 'visa' or ../type = 'mastercard'"/>

这里我们使用了“relevant” 属性, everything is relevant in the XForms instance. 如果定义了一个 "relevant"规则,XPath 表达式 会在结点集中判断每一个结点,如果一个表达式返回false,这个结点就会被忽略,并且隐藏(后面将详细说明).

   5. 最后如果是Visa或MasterCard检查校验码:

  <xforms:bind nodeset="verification-code" constraint="/credit-card/type = ('visa', 'mastercard') and . castable as xs:positiveInteger"/>
因为关联条件和约束条件所定义的结点相同,我们可以将上面两个绑在一起作为一个xforms:bind :

  <xforms:bind nodeset="verification-code" relevant="../type = 'visa' or ../type = 'mastercard'" constraint="/credit-card/type = ('visa', 'mastercard') and . castable as xs:positiveInteger"/>
在xforms:bind中定义XPath表达式 默认关联到第一个XForms实例的root根结点 :

    * 第一个XForms实例中指向根结点:

  <xforms:bind nodeset="number" type="xs:integer"/>

    * 第一个XForms实例中指向一个绝对路径:

  <xforms:bind nodeset="/credit-card/number" type="xs:integer"/>

    * 使用instance()函数来指向一个实例:

  <xforms:bind nodeset="instance('credit-card-instance')/number" type="xs:integer"/>
现在我们看一个例子,描述3种类型的属性:
Validation
    
“Validation“ 来确定结点或属性的内容是否有效.无效的值会影响表单的显示方式(可能对错误高亮,或显示一些提示信息). 而且XForms引擎不会提交无效的数据,这里定义了三种有效型检查:

    * required ― 属性值是否必填,值可以是true() 或XPath表达式,默认为false(not require).
    * type ― 属性值符合W3C XML Schema simple type。
    *

另外,XML schema 定义的类型有特殊的功能:

          o xs:date ― 录入的字段是通过弹出的日历来填充,日历可以通过 oxf:/config/theme/jscalendar 来定义
    * constraint ― 定义约束,支持XPath表达式的约束。

Calculation
    
完成自动计算的功能:

    * calculate ―使用XPath表达式来设置计算公式.含有计算属性的结点是只读的.

Visibility
    
通常XForms实例的结点默认是可读写和显示的,可以使用XPath表达式来设置值:

    * readonly ― 是否只读.
    * relevant ― 是否显示.

4.2. XForms 控件
4.2.1. 控件
XForms 控件通HTML表单类似:包括文本框,下拉框,复选框,单选框等。不同的是:

    * XForms控件显示的值来自于XForms实例的结点.如果声明一个控件需要使用ref属性指向到一个XForms实例的结点. 例如:

  <xforms:input ref="/credit-card/number"/>

    * 这样一个控件的状态通结点的属性是一致的,例如如果结点定义了只读则控件也是只读的;

下表显示了有效的XForms控件和使用方法的例子

Control
    
XForms in the view
    
Example
Text field

    
  <xforms:input ref="text"/>
    

XForms Controls
Password field

    
  <xforms:secret ref="secret"/>
    

XForms Controls
Text area

    
  <xforms:textarea ref="textarea"/>
    

XForms Controls
Radio buttons

    
  <xforms:select1 ref="carrier" appearance="full">  
<xforms:item>  
<xforms:label>Fedex</xforms:label>  
<xforms:value>fedex</xforms:value>  
</xforms:item>  
<xforms:item>  
<xforms:label>UPS</xforms:label>
<xforms:value>ups</xforms:value>  
</xforms:item>  
</xforms:select1>
    

XForms Controls
 
    
 
    
 
Single-selection lists

    
  <xforms:select1 ref="carrier" appearance="compact">  
<xforms:item>  
<xforms:label>Fedex</xforms:label>
        <xforms:value>fedex</xforms:value>  
</xforms:item>  
<xforms:item>  
<xforms:label>UPS</xforms:label>  
<xforms:value>ups</xforms:value>
 </xforms:item>  
</xforms:select1>
    

XForms Controls
Combo box

    
  <xforms:select1 ref="payment" appearance="minimal">  
<xforms:item>  
<xforms:label>Cash</xforms:label>  
<xforms:value>cash</xforms:value>  
</xforms:item>  
<xforms:item>  
<xforms:label>Credit</xforms:label>  
<xforms:value>credit</xforms:value>
  </xforms:item>  
</xforms:select1>
    

XForms Controls
Autocomplete box

    
  <xforms:select1 ref="name" selection="open" incremental="true" appearance="xxforms:autocomplete">  
<xforms:label class="label">Name:</xforms:label>  
<xforms:itemset nodeset="instance('countries-name')/country">  
<xforms:label ref="name"/>  
<xforms:value ref="name"/>  
</xforms:itemset>  
</xforms:select1>
    

Auto-Complete

 
Checkboxes

    
  <xforms:select ref="wrapping" appearance="full">  
<xforms:choices>  
<xforms:item>  
<xforms:label>Hard-box</xforms:label>  
<xforms:value>box</xforms:value>
  </xforms:item>  
<xforms:item>  
<xforms:label>Gift</xforms:label>  
<xforms:value>gift</xforms:value>  
</xforms:item>  
</xforms:choices>  
</xforms:select>
    

XForms Controls
List

    
  <xforms:select ref="taste" appearance="compact">
       <xforms:item>
              <xforms:label>Vanilla</xforms:label>
              <xforms:value>vanilla</xforms:value>
       </xforms:item>
       <xforms:item>
              <xforms:label>Strawberry</xforms:label>
              <xforms:value>strawberry</xforms:value>
       </xforms:item>
</xforms:select>
    

XForms Controls
Trigger button

    
<xforms:trigger>
       <xforms:label>Add carrier</xforms:label>
</xforms:trigger>
    

XForms Controls

 
Submit button

    
<xforms:submit submission="main-submission">
       <xforms:label>Submit</xforms:label>
</xforms:submit>
    
-
Submit link

    
 <xforms:submit submission="main-submission" appearance="xxforms:link">
       <xforms:label>Submit</xforms:label>
</xforms:submit>
    
-
Submit image

    

<xforms:submit submission="main-submission" appearance="xxforms:image">
       <xxforms:img src="images/submit.gif"/>
       <xforms:label>Submit</xforms:label>
</xforms:submit>
    
-
Upload

    
<xforms:upload ref="files/file[1]">
       <xforms:filename ref="@filename"/>
       <xforms:mediatype ref="@mediatype"/>
       <xxforms:size ref="@size"/>
</xforms:upload>
    

Upload Control
Range

    
<xforms:range ref="range/value">

       <xforms:send submission="countries-submission" ev:event="xforms-value-changed"/>
</xforms:range>
    

XForms Controls

在上面的例子里,select和select1的标题和值使用了多个<xforms:item> 元素. 另外也可以是使用<xforms:itemset>元素 代替多个<xforms:item> 元素:
  <xforms:select1 ref="country" appearance="compact">
       <xforms:itemset nodeset="instance('countries')/country">
              <xforms:label ref="name"/>
              <xforms:value ref="us-code"/>
       </xforms:itemset>
</xforms:select1>

4.2.2. Label, Alert, Help, 和 Hint
可以嵌在XForms控件元素中,可以定义附加的元素改变控件显示的方式:
Label   

默认的标签用来提交.

 

Alert  
每个控件都可以定义一个错误信息,当出现无效录入时显示.
  <xforms:secret ref="secret"> 
<xforms:alert>Invalid password</xforms:alert>  
  </xforms:secret>
    
 
Hint   
可以为控件定义提示信息,当控件被选中时高亮显示.
  <xforms:textarea ref="textarea">  

<xforms:hint>Enter at least 11 characters</xforms:hint>  

</xforms:textarea>

 

Help   
如果定义了帮助,在控件旁边会有一个帮助图标出现,点击图表会弹出一个帮助信息框.
<xforms:input ref="date" class="xforms-date">
       <xforms:label class="fixed-width">Birth date:</xforms:label>

       <xforms:help>This is supposed to be a help message explaining what a birth date is. But since you already know, it mostly serves the purpose of showing how help messages can be attached to controls, and that they can be pretty long as they can be displayed on multiple lines.
 </xforms:help>
</xforms:input>
 

在上面的例子中,需要显示的文本直接定义在 <xforms:label>, <xforms:alert>, <xforms:help>, 或 <xforms:hint>元素中.另外也可以使用值引用,例如:
  <xforms:secret ref="secret">  
<xforms:alert ref="@alert"/>  
</xforms:secret>
4.2.3. 上传

XForms 允许使用XForms Upload 控件上传文件:
  <xforms:upload ref="files/file[1]">  
<xforms:filename ref="@filename"/>  
<xforms:mediatype ref="@mediatype"/>  
<xxforms:size ref="@size"/>  
</xforms:upload>
关联的XForms实例节可以是::
  <files>  
<file filename="" mediatype="" size="" xsi:type="xs:anyURI"/>  
</files>
文件元素是一个存储上传文件的元素,有两种方式存储:

    * 作为一个 URL, 定义为xs:anyURI类型.
    * 作为 Base64-encoded 文本,定义为xs:base64Binary类型. Base64 是使用一个US-ASCII的子集来表示任何二进制数据. 参考RFC.

4.3. 使用xforms:repeat循环结点
4.3.1. 基础
在用户界面上经常有多行录入.单行的录入格式都相同,像表格一样。
XForms 提供了强大的方法来实现这样的结构: xforms:repeat 元素,例如有一个XForms实例:

<xforms:instance id="employees-instance" xmlns:xforms="http://www.w3.org/2002/xforms">
       <employees>
              <employee>
                     <first-name>Alice</first-name>
              </employee>
              <employee>
                     <first-name>Bob</first-name>
              </employee>
              <employee>
                     <first-name>Marie</first-name>
              </employee>
       </employees>
</xforms:instance>
使用循环的XForms:
<xforms:repeat nodeset="instance('employees-instance')/employee">
       <xhtml:tr>
              <xhtml:td>
                     <xforms:output ref="first-name"/>
              </xhtml:td>
       </xhtml:tr>
</xforms:repeat>
4.3.2. 使用 xforms:delete 方法删除结点
xforms:repeat 不仅是为了显示,也可以用来编辑多行数据,有两个相关的方法:删除和插入: xforms:delete 和 xforms:insert.
xforms:delete 的使用at属性来操作,例如:
  <!—删除最后一个元素-->  
<xforms:delete nodeset="employees" at="last()"/>  
<!—删除第一个元素-->  
<xforms:delete nodeset="employees" at="1"/>  
<!—删除当前的元素 (假设 'employee-repeat'是ID) -->  
<xforms:delete nodeset="employees" at="index('employee-repeat')"/>
4.3.3. 使用xforms:insert 方法来插入

xforms:insert 的nodeset 属性表示要插入得节点,例如:
  <!—在末尾结点前插入-->  
<xforms:insert nodeset="employees" at="last()" position="before"/>  
<!—在最后插入-->  
<xforms:insert nodeset="employees" at="last()" position="after"/>  
<!—在第一个结点前插入-->  
<xforms:insert nodeset="employees" at="1" position="before"/>  
<!--在第一个结点后插入-->  
<xforms:insert nodeset="employees" at="1" position="after"/>  
<xforms:insert nodeset="employees" at="last()" position="after"/>
<!—在当前选择结点前插入 -->
<xforms:insert nodeset="employees" at="index('employee-repeat')" position="before"/>  
<!—在当前选择结点后插入-->  
<xforms:insert nodeset="employees" at="index('employee-repeat')" position="after"/>
下面的方法是使用一个末尾空行来作为插入的模板

  <xforms:instance id="employees-instance" xmlns:xforms="http://www.w3.org/2002/xforms">
       <employees>
              <employee>
                     <first-name>Alice</first-name>
              </employee>
              <employee>
                     <first-name>Bob</first-name>
              </employee>
              <employee>
                     <first-name>Marie</first-name>
              </employee>
              <!—用来插入的模板-->
              <employee>
                     <first-name/>
              </employee>
       </employees>
</xforms:instance>
如果不想显示这个末尾的元素可以这样:

  <xforms:repeat nodeset="instance('employees-instance')/employee[position() &lt; last()]">...  
</xforms:repeat>
4.3.4. 使用xforms:trigger触发器执行 Action
插入和删除是用户按下按钮后比较典型的操作,我们可以在使用xforms:trigger在这些操作运行时添加新的元素:
<xforms:trigger>
       <xforms:label>Add</xforms:label>
       <xforms:action ev:event="DOMActivate">
              <xforms:insert nodeset="employees" at="index('employee-repeat')" position="after"/>
       </xforms:action>
</xforms:trigger>
or:
<xforms:trigger>
       <xforms:label>Delete</xforms:label>
       <xforms:action ev:event="DOMActivate">
              <xforms:delete nodeset="employees" at="index('employee-repeat')"/>
       </xforms:action>
</xforms:trigger>
为xforms:insert 和xforms:delete创建一个xforms:action的父结点. 因为只有一个Action要执行,xforms:action并不是必须的,但是可以提高代码的可读性,下面的写法也是正确的:
<xforms:trigger>
       <xforms:label>Add</xforms:label>
       <xforms:insert ev:event="DOMActivate" nodeset="employees" at="index('employee-repeat')" position="after"/>
</xforms:trigger>
或:
<xforms:trigger>
       <xforms:label>Delete</xforms:label>
       <xforms:delete ev:event="DOMActivate" nodeset="employees" at="index('employee-repeat')"/>
</xforms:trigger>
4.3.5. 嵌套循环
看下面的XForms实例:
<xforms:instance id="departments">
       <departments>
              <department>

                     <name>Research and Development</name>
                     <employees>
                            <employee>
                                   <first-name>John</first-name>
                            </employee>
                            <employee>
                                   <first-name>Mary</first-name>
                            </employee>
                     </employees>
              </department>
              <department>
                     <name>Support</name>
                     <employees>
                            <employee>
                                   <first-name>Anne</first-name>
                            </employee>
                            <employee>
                                   <first-name>Mark</first-name>
                            </employee>
                            <employee>
                                   <first-name>Sophie</first-name>
                            </employee>
                     </employees>
              </department>
       </departments>
</xforms:instance>
可以看出有两个节需要循环:

    * Departments: instance('departments')/department.
    * Employees:

instance('departments')/department/employees/employee.
下面的例子说明如何表示一个嵌套的循环:
  <xhtml:table>
       <xforms:repeat nodeset="instance('departments')/department">
              <xhtml:tr>
                     <xhtml:td>
                            <xforms:output ref="name"/>
                     </xhtml:td>
                     <xhtml:td>
                            <xhtml:table>
                                   <xforms:repeat nodeset="employees/employee">
                                          <xhtml:tr>
                                                 <xhtml:td>
                                                        <xforms:output ref="first-name"/>
                                                 </xhtml:td>
                                          </xhtml:tr>
                                   </xforms:repeat>
                            </xhtml:table>
                     </xhtml:td>
              </xhtml:tr>
       </xforms:repeat>
</xhtml:table>
在上面的代码中第二个 xforms:repeat结点表示对每一个父结点进行循环 .
4.4. Actions
4.4.1. 使用xforms:setvalue 来设置值
有两种方法:首先时设置<xforms:setvalue>结点的值,还有一种使用Value属性,可以设置值或XPath引用,下面是两种不同的方法:.
<xforms:trigger xmlns:xforms="http://www.w3.org/2002/xforms">
       <xforms:label>Submit</xforms:label>
       <xforms:action ev:event="DOMActivate">
              <xforms:setvalue ref="clicked">my-button</xforms:setvalue>
              <xforms:setvalue ref="flavor" value="concat('van', 'illa')"/>
       </xforms:action>
</xforms:trigger>

4.4.2. 所有xforms:message 显示消息


在界面上弹出消息对话框. OPS 使用服务端来实现
消息来源可以是绑定的属性 (ref 或 bind),或链接属性(src).顺序是 如下:

    * 绑定的属性
    * 链接属性
    * 内联文本

注意

    * 当使用链接属性时(src),必须为绝对的URL,以oxf:, http: 或其他支持的协议作为前缀.

<xforms:trigger>
       <xforms:label>Test</xforms:label>
       <xforms:message ev:event="DOMActivate" ref="taste"/>
</xforms:trigger>
4.5. 提交
在OPS中控制XForms提交的有两个属性:

<property as="xs:boolean" name="oxf.xforms.optimize-post-all" value="true"/>

如果设置为true(默认), OPS 直接发送到Web浏览器.就是说提交的错误不能被XForms事件捕捉, as should be the case following XForms 1.0. If set to false, OPS buffers the reply so that errors can be handled as per XForms 1.0. However, this solution is less efficient.

<property as="xs:boolean" name="oxf.xforms.optimize-local-submission" value="true"/>

    * 如果设置为true (默认), OPS能优化本地HTTP和HTTPS提交,例如使用Java Serverlet代替HTTP协议。
    * 如果设置为false, OPS总是使用HTTP或HTTPS协议来提交,可能效率比较低,在这种情况下,可以设置xforms:submission属性值为xxforms:post来代替post作为优化。

5. 格式
5.1. 基本原理

通常建议在XForms实例中使用原生的XML类型, 提高可用性和互用性。例如,日期 January 10, 2005 以ISO格式存储为: 2005-10-01. 然而经常需要按照用户习惯来表示例如,"January 10, 2005", "10 janvier 2005", or "10. Januar 2005". OPS 提供了一个扩展的属性 xxforms:format. xxforms:format 必须包括一个XPath 2.0 表达式. 在XPath 表达式种可以使用所有XPath2.0的函数,包括数据操作(参考文档). 然而因为XPath2。0没有提供关于日期和事件的格式操作,可以使用XSLT2。0函数:

    * format-date() (参考文档)
    * format-dateTime() (参考文档)
    * format-time() (参考文档)
    * format-number() (参考文档)

The XPath expression is evaluated by the XForms engine whenever the value bound to the xforms:input control changes and needs to be updated on screen. It is evaluated in the context of the instance node bound to the control. This means that the current value of the control can be accessed with ".". Often the value must be converted, for example to a date, in which case the conversion can be done with XPath 2.0 type casts such as xs:date(.).
5.2. xforms:input
当使用xforms:input 和 xs:date类型时,可以使用xxforms:format来控制日期的格式,例如:

<xforms:input ref="date" xxforms:format="format-date(xs:date(.), '[MNn] [D], [Y]', 'en', (), ())"/>
5.3. xforms:output
同样方法对xforms:output也一样

<xforms:output ref="date" xxforms:format="format-date(xs:date(.), '[MNn] [D], [Y]', 'en', (), ())"/>

<xforms:output ref="size" xxforms:format="format-number(., '###,##0')"/>
5.4. 默认格式
如果xs:date,xs:dateTime或xs:time没有定义xxforms:format则使用默认的格式来显示,下面时默认格式:

l        <property as="xs:string" name="oxf.xforms.format.date" value="if (. castable as xs:date) then format-date(xs:date(.), '[FNn] [MNn] [D], [Y]', 'en', (), ()) else ."/>
 
2004-01-07显示为 Wednesday January 7, 2004
 

l        <property as="xs:string" name="oxf.xforms.format.dateTime" value="if (. castable as xs:dateTime) then format-dateTime(xs:dateTime(.), '[FNn] [MNn] [D], [Y] [H01]:[m01]:[s01] UTC', 'en', (), ()) else ."/>
2004-01-07T04:38:35.123 显示为 Wednesday January 7, 2004 04:38:35 UTC
 

l        <property as="xs:string" name="oxf.xforms.format.time" value="if (. castable as xs:time) then format-time(xs:time(.), '[H01]:[m01]:[s01] UTC', 'en', (), ()) else ."/>

04:38:35.123 显示为 04:38:35 UTC
posted on 2009-02-17 11:17  凌枫  阅读(507)  评论(0)    收藏  举报