XForms 入门简介,第 2 部分: 表单、模型、控件和提交动作

XForms 是下一代的基于 Web 的数据处理技术。它用 XML 数据模型和表示元素代替了传统的 HTML 表单。本系列文章有三个部分,介绍了 XForms 及其功能,内容包括基本的 XForms 模型和表单、各种不同类型的控件、基本和高级表单提交技术。本文是此系列文章的第二部分,重点讨论如何使用各种控件创建基于 XForms 的表单以及如何创建数据模型。

Chris Herborth, 自由作家, Freelancer

Photo of Chris HerborthChris Herborth 是一位广受好评的高级技术作家,有超过 10 年的操作系统和编程方面的写作经验。Chris 业余时间喜欢陪他的儿子 Alex 玩耍或与妻子 Lynette 闲逛,其余时间都在进行设计、写作或研究(玩)视频游戏。



2006 年 12 月 31 日

简介

XForms 的发展势头迅猛,常见浏览器使用扩展或插件来支持它,此外还有 IBM® Workplace Forms 之类的技术(请参见参考资料部分)。它的灵活和强大对 Web 开发人员很有吸引力,内存占用少和客户端处理又让系统管理员十分感兴趣。W3C 正在审查 XForms 1.1 工作草案文档(1.0 是正式的 Internet 推荐标准,和 XHTML、PNG 以及 CSS 具有同等的地位),IBM 目前带头致力于把那些竞争的基于 XML 的表单标准与 XForms 的特性和功能结合起来。

本文说明了如何使用各种控件创建基于 XForms 的表单、如何建立数据模型以及不同类型的基本提交动作。第 1 部分讨论了各种浏览器以及为了查看和与 XForms 文档交互所需要的插件,本文不再赘述。如果阅读过上一部分,或者已经为使用的浏览器安装了插件,可以直接下载本文中的代码查看示例 XForms。


创建基本的表单

本系列的第 1 部分中已经创建了一个非常简单的表单,其中包括一个文本输入字段和一个提交按钮,可以向本地主机上假想的搜索引擎发送请求(如图 1 所示)。这类表单仍然很常见,尽管它通常不是孤立在单独的网页上。

图 1. 非常简单的 Web 表单
非常简单的 Web 表单

这是个很好的起点,我们再来看看 XHTML 和 XForms 代码(清单 1)。XForms 的专用代码用粗体字显示,很容易看到,文档的其他部分是纯粹的 XHTML 1.1 Strict。

清单 1. 起点
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xf="http://www.w3.org/2002/xforms"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
<title>Search Form</title>
<xf:model>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>
</head>
<body>
<h1>Search Form</h1>

<p>
Enter a search string, then click the Search button.
</p>

<p>
<xf:input ref="query"><xf:label>Find:</xf:label></xf:input>
<xf:submit 
submission="submit-search"><xf:label>Search</xf:label>
</xf:submit>
</p>
</body>
</html>

增加 XForms 名称空间(使用 xf: 前缀)后,已经有了一个 <xf:model> 块,它声明了名为 submit-search 的提交动作,可以使用标准的 HTTP GET 方法提交指定的搜索字符串。<body>, <xf:input><xf:submit> 元素中的内容构成了简单的表单,包括输入字段和提交按钮,后者触发 <xf:model> 中声明的动作。

如果愿意的话,可以直接试一试,<xf:input><xf:submit> 元素的距离、先后或位置没有任何特殊要求,它们可以出现在文档 <body> 的任何地方。表单的输入部件表示与其数据模型分离开来。

由于将使用该文档作为本文中其他 XForms 文档的出发点,这里还提供了 XMLSchema 和 xml-events 的 XML 名称空间声明,XForms 利用这两个辅助标准分别提供标准数据类型和表单事件。


创建一个简单的模型

XForms 的吸引人的原因之一是其将数据模型从表示中分离出来的方法。再看看清单 1,模型(<xf:model> 块中)本身存在于 XHTML 文档的 <head> 中。

当然,除了一个提交动作之外这个模型完全是空的。它不含任何数据!

不过,先别忙。系统(在这里就是支持 XForms 的浏览器)为您创建了一个(如清单 2 所示),其中包含表单引用的数据字段。

清单 2. 简单表单默认的完整 <xf:model>
<xf:model>
    <xf:instance>
        <data xmlns="">
            <query/>
        </data>
    </xf:instance>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>

显式地包含这种形式的实例为表单额外增加了一层验证;表单控件(比如这个简单表单中的文本字段和提交按钮)所引用的字段必须存在于模型实例之中。引用不存在的实例元素的控件要么不能呈现,要么生成错误消息(取决于 XForms 实现)。


默认值

如果显式地声明数据实例,可用它来定义默认值,只要将默认值放在字段元素中即可。清单 3 中的模型和清单 2 相同,只不过为查询提供了一个有帮助的默认值(如图 2 所示)。

清单 3. 在 <xf:instance> 中直接包含默认值
<xf:model>
    <xf:instance>
        <data xmlns="">
            <query>One or more search keywords.</query>
        </data>
    </xf:instance>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>
图 2. 在模型实例中包含帮助性的提示或者有意义的默认值
在模型实例中包含帮助性的提示或者有意义的默认值

隐藏值和隐藏控件

用户触发提交动作时,XForms 发送完整的 XML 文档(数据模型实例)。创建模型实例时可以包含需要的任何数据。

因而不再需要在表单中使用隐藏控件。如果有些数据需要发送到服务器上的表单处理程序,但是又不必显示给用户(或者需要保持不变),那么可以将其添加到模型实例中(如清单 4 所示)。

清单 4. 在实例而不是表单中包含隐藏数据或者常量
<xf:model>
    <xf:instance>
        <data xmlns="">
            <query>One or more search keywords.</query>
            <engine-version>2</engine-version>
            <results>25</results>
        </data>
    </xf:instance>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>

该例中,<engine-version><results> 永远不会被表单控件引用,也不会被用户看到(除非用户查看源代码)。这些数据组作为查询的一部分发送给 imaginary-search-engine,imaginary-search-engine 可以利用它们选择搜索引擎和设置返回的结果数。


加载实例

如果数据模型很大,或者需要向用户隐藏某些数据,可以从外部 XML 文件加载实例(如清单 5 所示)。

清单 5. XML 文件中的简单模型实例
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="">
    <query>One or more search keywords.</query>
    <engine-version>2</engine-version>
    <results>25</results>
</data>

只要让 <xf:instance> 引用具体的实例 URL(如清单 6 所示)就可以了。

清单 6. 引用外部模型实例
<xf:model>
    <xf:instance src="search-instance.xml"/>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>

由于 <xf:instance>src 属性可以从任何 URL 加载 XML 数据,可以用 XForms 编辑或原样表示任何数据。多数 XForms 实现都要求源文档的 URL 在同一个域中,但部分 XForms 实现也允许您配置一个可信任的站点列表。


XML 数据中的引用

加载 XML 文件作为数据实例时,有可能无法控制 XML;数据也许是数据库或者其他某个应用程序提供的。如何引用 XML 中的某个元素呢?到目前为止,您还只看到了引用与数据模型匹配的元素。

XForms 表单元素使用的数据模型引用实际上是 XPath 表达式,因此可用 XPath 表达式来引用模型中的任何元素。清单 7 显示了一个扩展后的实例,其中包括一些嵌套元素。

清单 7. 更复杂的数据模型实例
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="">
    <query>One or more search keywords.</query>
    <engine-version>2</engine-version>
    <results>25</results>
    <some>
        <additional>
            <info status="important">Nested info.</info>
        </additional>
    </some>
</data>

可用 XPath 表达式 some/additional/info(或者 /data/some/additional/info,如果使用绝对路径的话)来访问 <info> 元素,或者用 some/additional/info/@status 访问 <info> 元素的 status 属性。清单 8 显示了可用于编辑该数据文件的表单,在这里假设 Web 服务器支持 PUT 方法(可能需要某种身份验证来保护这种功能)。

清单 8. 编辑更复杂的 XML 数据
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xf="http://www.w3.org/2002/xforms">
<head>
<title>Search Form</title>
<xf:model>
    <xf:instance src="http://localhost/~chrish/data.xml"/>
    <xf:submission action="http://localhost/~chrish/data.xml" 
        method="put" id="submit-edit"/>
</xf:model>
</head>
<body>
<h1>XPath</h1>

<p>
Change the info and status!
</p>

<p>
<xf:input ref="some/additional/info"><xf:label>New 
info:</xf:label></xf:input><br/>
<xf:input ref="some/additional/info/@status"><xf:label>New 
status:</xf:label></xf:input>
<xf:submit 
submission="submit-edit"><xf:label>Save</xf:label></xf:submit>
</p>
</body>
</html>

无论在客户机还是服务器上,对 XForms 来说 XPath 都是一种很好的辅助技术;一旦掌握了 XPath,就可以在表单和表单处理程序中使用它。


控件的类型

到目前为止,我们只用到了 <xf:input><xf:submit> 控件,但是 XForms 还提供了很多其他的表单控件。我们来看看这些控件及其在 HTML 中的等价物。

<xf:group>(HTML <fieldset>)用于对表单中的控件进行逻辑分组。清单 9 说明了如何使用 <xf:group> 为三个输入字段加标签。

清单 9. 分组控件
<xf:group>
   <xf:label>Personal Information</xf:label>
   <p><xf:input ref="lastname"><xf:label>Last 
name:</xf:label></xf:input></p>
   <p><xf:input ref="firstname"><xf:label>First 
name:</xf:label></xf:input></p>
   <p><xf:input 
ref="address"><xf:label>Address:</xf:label></xf:input></p>
</xf:group>

<xf:input>(HTML <input type="text">)显示一个标准的文本输入字段,我们已经多次用到了它。

<xf:secret>(HTML <input type="password">)显示一个文本输入字段,输入的内容隐藏起来,适用于输入口令或者其他保密数据。<xf:secret> 与文档源代码中的 <xf:input> 完全相同。

<xf:select appearance="full">(HTML <input type="checkbox">)为用户提供一个或多个可选项,允许多选。清单 10 给出了一个例子。

清单 10. 多选控件
<xf:select ref="potato-chips" appearance="full">
   <xf:label>Favourite flavours:</xf:label>
   <xf:item><xf:label>Dill 
Pickle</xf:label><xf:value>dill</xf:value></xf:item>
   
<xf:item><xf:label>Ketchup</xf:label><xf:value>ketchup<
/xf:value></xf:item>
   
<xf:item><xf:label>Plain</xf:label><xf:value>plain<
/xf:value></xf:item>
   <xf:item><xf:label>Salt & 
Vinegar</xf:label><xf:value>snv</xf:value></xf:item>
</xf:select>

<xf:select appearance="minimal">(HTML <select multiple>)用于从菜单或列表中选择一个或多个项,对 appearance 属性使用 minimal 可以在更小的区域中呈现项目列表。

<xf:select1>(HTML <input type="radio">)类似于 <xf:select>,但是只允许用户从列表中选择一项。它可以呈现为一组单选按钮、可滚动的选择区域或者菜单,使用 appearance 属性告诉呈现引擎应该呈现为什么。

<xf:select1> 和嵌套的 <xf:choices>(HTML <select> 和嵌套的 <optgroup>)允许用户从分组列表中选择一项。<xf:choices> 子列表的标签呈现在列表中,但是不能选择。清单 11 显示了一个饮料列表让用户选择,用户也可以从非酒精和酒精饮料中选择。

清单 11. 从多个分组中选择一项
<xf:select1 ref="drink">
   <xf:label>Drink:</xf:label>
   <xf:item><xf:label>None</xf:label><xf:value>none
</xf:value></xf:item>
   <xf:choices>
      <xf:label>Soft drinks</xf:label>
      
<xf:item><xf:label>Juice</xf:label><xf:value>juice
</xf:value></xf:item>
      
<xf:item><xf:label>Milk</xf:label><xf:value>milk
</xf:value></xf:item>
      
<xf:item><xf:label>Soda</xf:label><xf:value>soda
</xf:value></xf:item>
      
<xf:item><xf:label>Water</xf:label><xf:value>water<
/xf:value></xf:item>
   </xf:choices>
   <xf:choices>
      <xf:label>Wine and beer</xf:label>
      
<xf:item><xf:label>Beer</xf:label><xf:value>beer<
/xf:value></xf:item>
      <xf:item><xf:label>Red 
wine</xf:label><xf:value>redwine</xf:value></xf:item>
      <xf:item><xf:label>White 
wine</xf:label><xf:value>whitewine</xf:value></xf:item>
   </xf:choices>
</xf:select1>

<xf:textarea>(HTML <textarea>)显示一个多行文本输入字段,如果默认值不合适可使用 CSS 样式控制区域的大小。

<xf:trigger>(HTML <input type="button">)呈现一个动作按钮。按钮没有预定义的行为,因此需要为其附加一个动作,按钮被激活时将触发该动作。清单 12 中的 <xf:trigger> 激活一个 JavaScript™ 函数,名为 calculate()

清单 12. 调用 JavaScript 函数 calculate() 的按钮
<xf:trigger>
    <xf:label>Calculate</xf:label>
    <script ev:event="DOMActivate" type="text/javascript">
    calculate();
    </script>
</xf:trigger>

要注意,这里第一次使用 ev: 名称空间,虽然在前面的基本表单的示例中早已声明。它用于引用标准 XML Events 属性 ev:event,它告诉触发器什么时候激活脚本。

<xf:trigger>(HTML <input type="image">)也可用于为表单添加图像按钮,只需在 <xf:label> 元素中插入 <img> 元素或者使用 CSS 将图像作为元素的背景即可。

如果正在把某些 HTML 表单升级到 XForms 表单,可以使用 <xf:trigger>(HTML <input type="reset">)增加 Reset 按钮(升级规范可能要求“全部功能”,包括无用的 Reset 按钮)。清单 13 说明了如何创建一个表单复位按钮,但是不要在新表单中使用它:最终用户永远不会有意识地单击 Reset 按钮。

清单 13. 实现无用的历史遗留物:Reset 按钮
<xf:trigger>
    <xf:label>Reset</xf:label>
    <xf:reset ev:event="DOMActivate"/>
</xf:trigger>

<xf:upload>(HTML <intput type="file">)用于实现文件上传。和其他控件相比这个更复杂一点,因为它需要一种特殊的 <xf:submission> 方法:form-data-post(如清单 14 所示)。

清单 14. 使用 <xf:submission> 方法上传文件
<xf:model>
   ...
    <xf:submission action="http://localhost/upload-engine"
        method="form-data-post" id="upload"/>
</xf:model>

表单下方的 <xf:upload> 元素看起来类似于 <xf:submit><xf:input>(如清单 15 所示)。

清单 15. 使用 <xf:upload> 上传文件
<xf:upload ref="upload"><xf:label>Upload a
 file:</xf:label></xf:upload>

另外,还有一些 HTML 中不存在的控件。

<xf:output> 允许在文档中增加一些文本值。比如清单 7 中向数据模型增加了 <results> 元素。虽然用户不能修改它,但是可以通过编辑模型来改变它(特别是如果使用外部 XML 文件中定义的模型的话)。可以使用 <xf:output> 元素向用户显示这些信息(如清单 16 所示)。

清单 16. 使用 <xf:output> 显示模型中的数据
<p>
Your search will return a maximum of
<xf:output ref="results"> matches.
</p>

<xf:range> 为用户显示一个范围选择条(slide)或者适合于获得受约束值的其他控件。比方说,可以用三个 range 让用户输入红/绿/蓝中的一个作为突出显示搜索结果的颜色(如清单 17 所示)。

清单 17. 使用范围输入控件
<p>
Keyword highlight:<br/>
<xf:range ref="r" start="0" end="100" step="1"><xf:label>Red</xf:label></xf:range><br/>
<xf:range ref="g" start="0" end="100" step="1"><xf:label>Green</xf:label></xf:range><br/>
<xf:range ref="b" start="0" end="100" step="1"><xf:label>Blue</xf:label></xf:range>
</p>

现在介绍了各种 XForms 输入控件(和一个输出控件),下面来看看各种不同的提交动作。


基本提交动作

XForms 标准支持通常的 HTML 表单提交方法,但是 HTML 需要 methodenctype 来指定提交方法,而 XForms 只需要一个 method

<xf:submission method="form-data-post" action="url"/> 和 HTML 中的 <form method="post" enctype="multipart/form-data"> 相同,可以按同样的方法在收到 URL 时被处理。

<xf:submission method="get" action="url"/> 和 HTML 中的 <form method="get"> 相同。

<xf:submission method="urlencoded-post" action="url"> 和 HTML 中的 <form method="post" enctype="application/x-www-form-urlencoded"> 相同。

除了和 HTML 兼容的提交方法之外,XForms 还定义了两种新的提交动作,method="post"method="put"

method="post" 动作将表单数据模型实例作为 XML 文档 post 给接收 URL,适用于 XSLT 或者其他 XML 处理技术。客户机不需要制定编码或者转义,服务器上也不需要特殊处理(除了标准 XML 解析以外)。

method="put" 动作将表单数据模型实例作为 XML 文档 put 给目标 URL。如果服务器支持 PUT 方法,并且允许对目标 URL 使用该方法,该 XML 文档将代替目标 URL 上的文件。可利用该方法现场编辑“任何”XML 文档,只需要通过和后来 put 动作要用到的相同的 URL 加载数据模型实例即可。

纯 XML postput 方法是 XForms 目标的一部分,为数据处理带来了一定程度的灵活性。


结束语

XForms 提供了一致的、清晰的基于 XML 的数据模型,可以在文档或者页面处理期间加载的外部文件中直接包含任意的 XML。该标准支持现在所有 HTML 表单控件的等价物,并增加了另外两个有用的控件用于范围选择和显示数据。基本 XForms 提交动作包含了原来的 HTML 的提交方法,并增加了两种基于 XML 的方法。本文全面介绍了这些控件,您可以以此为基础开始自己的 XForms 体验。


下载

描述名字大小
第 2 部分示例代码xforms2.zip3KB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML
ArticleID=186427
ArticleTitle=XForms 入门简介,第 2 部分: 表单、模型、控件和提交动作
publish-date=12312006