IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML  >

在 Firefox 中使用 XForms

通过实践学习 XForms

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Elliotte Rusty Harold (elharo@metalab.unc.edu), 副教授, Polytechnic University

2007 年 4 月 23 日

使用久经考验的 Mozilla XForms 扩展,现在您可以在浏览器中处理 XForms。虽然还没有在公共 Internet 上得到广泛部署,但 XForms 可能适合于某些内部网应用程序。本文演示了目前受 Firefox 和 Mozilla XForms 插件支持的基本的 XForms 处理。

XForms 使得通过 Web 部署的应用程序的开发更快更简单。XForms 清晰的体系结构使应用程序更健壮、更容易扩展、更快并且更安全。除了一点细节之外,用 XForms 进行开发不用费多少脑筋。这个细节就是目前的浏览器不能够直接支持 XForms 的。无需多说这个问题严重限制了 XForms 的用途和部署的范围。

不过也有解决的办法。Windows® Internet Explorer® 和 Firefox 都有浏览器插件可以在这两种市场上领先的浏览器上增加 XForms 支持。还有用 Flash 编写的 XForms 处理程序,可以部署到任何支持 Flash 运行时的浏览器上。最后还有服务器端解决方案,将所有的 XForms 标记预编译成传统的超文本标记语言(HTML)和 JavaScript 程序。

这些解决方案各有所长,但是对于初学 XForms,如果浏览器本身支持的话就更简单了。可以编写一个表单然后预览。之后稍作一些修改并再次预览。如果表单看起来不够满意,就再修改再查看。服务器端解决方案如 Chiba 非常适合部署,但是对于学习来说,什么也比不上浏览器的快速开发周期。因此,本文主要讨论在 FireFox 中使用 Mozilla XForms 插件。

安装插件

撰写本文时 Mozilla XForms 插件的当前版本为 0.7.0.1,支持 Firefox 1.5 及更高版本。安装插件很简单。在 Firefox 中打开 https://addons.mozilla.org/firefox/824/,然后单击那个大大的绿色 Install now 按钮,如图 1 所示:


图 1. 安装 Mozilla XForms 插件
Install now for MacOSX (425 KB)

这样将打开图 2 所示的对话框。该插件还没有签名,但是我希望它能够像任何 beta 软件一样安全。(加载混乱的内容时真的有两次把我的浏览器当掉了,这一点很容易受到拒绝服务攻击,因此我不知道是否应该推荐在真正的产品环境中使用它。)这些代码的目标是最终成为所有 FireFox 和 Mozilla 下载包的一部分,尽管结果很难说。


图 2. 安装 Mozilla XForms 对话框
A Web site is requesting permission to install the following item: Mozilla XForms 0.7 Unsigned

为了使该插件生效需要重新启动 Firefox,但这样就足够了。现在已经为编写和查看您的第一个 XForms 表单做好准备了。





回页首


Hello XForms

为了保证能够正确安装和运行,首先编写一个简单的 Hello World 例子,不需要和服务器通信。仅仅将一个字段的数据复制到另一个字段。包含该表单的可扩展标记语言(XHTML)文档如 清单 1 所示。

清单 1. 包含简单 XForms 表单的 XHTML 文档

                <html xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:xforms="http://www.w3.org/2002/xforms">
 <head>
 <title>Hello XForms!</title>
 <xforms:model>
 <xforms:instance xmlns="">
 <Name/>
 </xforms:instance>
 </xforms:model>
 </head>
 <body>
 <xforms:input ref="/Name">
 <xforms:label>Type your name in the box and press tab: </xforms:label>
 </xforms:input>
 <hr />
 <xforms:output value="concat('Hello ', /Name)">
 <xforms:label>Output: </xforms:label>
 </xforms:output>
 </body>
</html>

将这些代码保存到文件 hello.xhtml 中(不是 hello.html)。在 Firefox 中打开。应该能够在输入字段中输入内容,按下 Tab 键后可以看到 图 3 所示的结果。(只要不把焦点放到输入字段中就不需要按下 Tab 键。)


图 3. Hello XForms
Hello Elliotte Rusty Harold

也可以将该文件放在 Web 服务器上然后用 URL 装载。但是服务器必须发送媒体类型为 application/xhtml+xml 而不是 text/html 的文档,否则 Firefox 就不能识别 XForm。

该表单包括三部分:模型、输入部分和输出部分。复杂的表单可能包含更多部分,包括多个输入和输出部分,但是作为起点来说这个例子就足够了。

模型就是一个可扩展标记语言(XML)元素,所有的输入输出都能通过 XPath 表达时引用它。input 元素的 ref 属性指定了该输入将把数据存储在模型中的哪个部分。这里只有一个输入,将数据保存到 Name 元素中。

output 元素显示它的 value 属性中的文字。该 value 属性用 XPath concat 函数把文字串 'Hello' 和模型的 Name 元素的当前值连起来。这里可以放任何 XPath 表达式,包括算术和其他基本计算的表达式。不需要在每次操作时都和服务器交互。





回页首


选择要收集的数据

设计新的 XForm 时,通常首先要知道采集什么数据而不是表单是什么样子。本文给出了一个收集信用卡信息的例子。很多电子商务网站上都能看到类似的表单。需要收集的信息如下:

  • 信用卡的用户名,字符串
  • 信用卡号,13 或 16 位数字组成的字符串,包括一个校验位
  • CVV2 或信用卡标识编码(American Express 采用四位数字,Visa、MasterCard 和 Discover Card 都是三位数字)
  • 有效期,年月
  • 地址行 1,字符串
  • 地址行 2,字符串
  • 市,字符串
  • 州,从枚举出的五十多个双字母字符串中选一(为了简化,本例中只留下四个州)
  • 邮政编码,五或十个字符组成的字符串,包括数字和连字符
  • 信用卡类型(由四个字符串构成的枚举式列表)

所有的信息都指定了相应的类型。这样做对于验证是必须的。可以用 XML 模式验证大部分类型(尽管还不是全部)。

HTML 表单通常用 x-www-formurlencoded 查询字符串提交数据。对于安全的作为 URL 一部分传递的 GET 请求,XForms 也对它使用 x-www-formurlencoded。这是一种受限制的格式,只能包含名值对。但是对于 POSTPUT 请求,XForms 提交完整的 XML 文档。文档的模式由使用者决定。可以采用任何形式,只要方便在另一端处理即可。比如,可以采用 Atom 文档、SOAP 文档,也可以是针对需要采集的数据自定义的格式。对于该例而言,一个简单的列表就足够了,如 清单 2 所示:

清单 2. 包含(虚构的)信用卡信息的 XML 文档

                <CreditCardInfo>
 <Name>Elliotte Rusty Harold</Name>
 <Number>5123 4567 8901 2345</Number>
 <CVV2>314</CVV2>
 <Expiration>2007-01</Expiration>
 <Address1>6 Metrotech Center</Address1>
 <Address2>Dept. of Computer Science</Address2>
 <City>Brooklyn</City>
 <State>NY</State>
 <Zip>11201</Zip>
</CreditCardInfo>

模式可用于在客户端或服务器端验证该文档。 清单 3 给出了一种可能的模式。

清单 3. 信用卡数据的 W3C 模式

                <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

 <xs:element name="CreditCardInfo">
 <xs:complexType>
 <xs:sequence>
 <xs:element name="Name" type="xs:normalizedString"/>
 <xs:element name="Number" type="CardNumber"/>
 <xs:element name="CVV2" type="CVV2"/>
 <xs:element name="Expiration" type="xs:gYearMonth"/>
 <xs:element name="Address1" type="xs:normalizedString"/>
 <xs:element name="Address2" type="xs:normalizedString" minOccurs="0"/>
 <xs:element name="City" type="xs:normalizedString"/>
 <xs:element name="State" type="State"/>
 <xs:element name="Zip" type="ZipCode"/>
 </xs:sequence>
 </xs:complexType>
 </xs:element>

 <xs:simpleType name="CardNumber">
 <xs:restriction base="xs:string">
 <!-- 13 or 16 digits with optional spaces --> 
 <xs:pattern value="(\d\d\d\d ?)(\d\d\d\d ?)(\d\d\d\d ?)(\d(\d\d\d)?)"/>
 </xs:restriction>
 </xs:simpleType>

 <xs:simpleType name="ZipCode">
 <xs:restriction base="xs:string"> 
 <xs:pattern value="\d\d\d\d\d(-\d\d\d\d)?"/>
 </xs:restriction>
 </xs:simpleType>

 <xs:simpleType name="CVV2">
 <xs:restriction base="xs:string"> 
 <xs:pattern value="\d\d\d\d?"/>
 </xs:restriction>
 </xs:simpleType>

 <xs:simpleType name="State">
 <xs:restriction base="xs:token">
 <xs:enumeration value="AA"/>
 <xs:enumeration value="AK"/>
 <xs:enumeration value="AZ"/>
 <xs:enumeration value="NY"/>
 <!-- other states follow... -->
 </xs:restriction>
 </xs:simpleType>

</xs:schema>

Firefox 拒绝提交无效的数据。(令人不快的是,它没有提供任何有用的反馈信息,告诉用户提交的数据无效、哪个字段的数据无效或者如何解决。)但是服务器仍然要进行自己的有效性检查。相信客户机总是发送有效数据的服务器等于是请求别人的攻击。

此外,还有很多模式不能检查的约束和规则。最明显的是,它不能检查该信用卡是否被授权交易。也不能检查信用卡的校验位。只能用传统编程语言编写代码来检查这些约束。





回页首


模型

决定了要采集的数据之后还需要制作 模型。模型就是一个实例文档,没有输入数据,但是保留了标记和静态文本。 清单 4 给出了一个例子。它包括 XForms model 元素,该元素分为两部分:instancesubmissioninstance 包含 清单 2 中的实例文档,只不过去掉了其中的数据。这些数据将用表单输入填入。剩下的只有结构。

submission 元素指定了数据将被发送到的 URL 和发送的方法 GETPOST

模型还可以通过 schema 属性引用输入文档的模式。但这不是必需的,而且目前来说 Firefox 将忽略该属性。

清单 4. 信用卡数据的 XForms 模型

                <xforms:model schema="cc.xsd">
 <xforms:instance>
 <CreditCardInfo xmlns="">
 <Name />
 <Number />
 <CVV2 />
 <Expiration />
 <Address1 />
 <Address2 />
 <City />
 <State />
 <Zip />
 </CreditCardInfo>
 </xforms:instance>
 <xforms:submission action="http://example.com/xform-processor" 
 method="post" id="submit" />
</xforms:model>

模型放在包含表单的 XHTML 文档 head 中,和 titlemeta 以及属于 head 的其他任何标签相邻。





回页首


表单

和 HTML 表单一样,input 也是基本的元素。每个输入控件必须有一个标签告诉用户这里需要输入什么。这些提示文字由 input 的子元素 label 提供。比如下面的姓名输入字段:

<xforms:input ref="Name">
 <xforms:label>Credit Card Number:</xforms:label>
</xforms:input></xforms:label>

可将 input 元素放在主体中能够放置其他任何 inline 或 block 元素的位置。比如 strongp。和 HTML 表单不同的是,没有包含所有输入字段的主表单元素。可以和 HTML 元素方便地混在一起。

还需要一个提交控件将表单发送到模型中 submission 元素指定的 URL。只不过是一个包含 labelsubmit 元素:

<xforms:submit submission="submit">
 <xforms:label>Buy Now!</xforms:label>
</xforms:submit>

清单 5 显示了表单的代码。

清单 5. 信用卡数据的 XForms 输入字段

                <xforms:input ref="Name">
 <xforms:label>Name as it appears on the credit card:</xforms:label>
</xforms:input>

<xforms:input ref="Number">
 <xforms:label>Credit Card Number:</xforms:label>
</xforms:input>

<xforms:input ref="CVV2">
 <xforms:label>CVV2:</xforms:label>
</xforms:input>

<xforms:input ref="Expiration">
 <xforms:label>Expiration date:</xforms:label>
</xforms:input>

<xforms:input ref="Address1">
 <xforms:label>Address Line 1:</xforms:label>
</xforms:input>

<xforms:input ref="Address2">
 <xforms:label>Address Line 2:</xforms:label>
</xforms:input>

<xforms:input ref="City">
 <xforms:label>City:</xforms:label>
</xforms:input>

<xforms:input ref="State">
 <xforms:label>State:</xforms:label>
</xforms:input>

<xforms:input ref="Zip">
 <xforms:label>Zip code:</xforms:label>
</xforms:input>

<xforms:submit submission="submit">
 <xforms:label>Buy Now!</xforms:label>
</xforms:submit>

图 4 显示了表单在 Firefox 中显示的结果。


图 4. 信用卡数据输入表单
输入表单

这个表单还很粗糙,但是很快我们将用级联样式表(CSS)来美化。





回页首


其他控件

input 控件的意思是 “从用户得到一个文本字符串”。但是还有其他表单中经常用到的一般操作。具体而言,XForms 定义了十种通用的表单控件,用不同的元素表示:

  • 输入一行文本: input
  • 提交表单: submit
  • 向用户显示不能编辑的计算结果: output
  • 从列表中选择一项: select1
  • 从列表中选择零或多项: select
  • 从用户处获得多行文本: textarea
  • 输入一行文本但是不显示出来: secret
  • 选择一个文件: upload
  • 从一个范围中选择: range
  • 启动脚本: trigger

多数控件都有自己的小部件。比如,Firefox 使用按钮表示 trigger,使用滑动条表示 range,使用标准文件打开对话框表示 upload 控件。secret 控件就是一个文本字段,和 input 完全相同,只不过用户输入的内容在屏幕上用圆点表示。只要让用户输入相同类型的数据,不同浏览器可以显示不同的东西。

比如,一种浏览器可能把 select1 显示成弹出菜单或者组合框,另一种浏览器则使用单选按钮,第三种则显示为滚动列表。第四种也许根据列表项的多少选择不同的形式。表单没有说应该呈现为什么样子。它只是说浏览器应该向终端用户显示一些选项并允许他们从中选择一项。

除了上面提到的三种控件之外,最适合该例子的是 select1。该控件非常适合输入一个州。我不想让用户输入任何文字,只要从列表中选择一个州就行了。各个选项用 select1 元素的子元素 item 表示,如清单 6 所示。

清单 6. 列举州名的 select1 控件

                <xforms:select1 ref="State">
 <xforms:label>State:</xforms:label>
 <xforms:item>
 <xforms:label>AA</xforms:label>
 <xforms:value>AA</xforms:value> 
 </xforms:item>
 <xforms:item>
 <xforms:label>AK</xforms:label>
 <xforms:value>AK</xforms:value> 
 </xforms:item>
 <xforms:item>
 <xforms:label>CA</xforms:label>
 <xforms:value>CA</xforms:value> 
 </xforms:item>
 <xforms:item>
 <xforms:label>NY</xforms:label>
 <xforms:value>NY</xforms:value> 
 </xforms:item>
 <!-- more states follow -->
</xforms:select1>

图 5 显示了该控件在 Firefox 的样子。


图 5. 选择州的 select1 控件
select1

每个项都包含标签和值。该例中两者是一致的,虽然这不是必需的。标签显示给最终用户。值在表单提交时发送给服务器。比如,翻译该页面时可以本地化标签而保持值不变。或者向用户显示完整的州名而向服务器发送缩写:

 <xforms:item>
 <xforms:label>Alabama</xforms:label>
 <xforms:value>AA</xforms:value> 
 </xforms:item>





回页首


控制外观

XForms 实际上并没有说 input 控件看起来是什么样。图 4 中不过用传统的图形用户界面(GUI)文本字段表示。在其他环境中可能看起来完全不同,只要能让用户输入一行文本即可。但是有些控件可能有更多限制而不仅仅是一行文本。比如,有效期只能接受特定格式的实际的日期数据。XForms 实现允许(尽管不要求)利用预期数据类型的信息以不同部件表示同一个控件。比如,如果 Firefox 知道要输入日期,可以向用户显示一个 图 6 所示的日历控件而不是常见的文本字段。


图 6. XForms 日历控件
有效期:日历

Firefox 可以读入实例模式确定提供哪种控件。但即便文档没有模式,仍然有各种方法将某种类型绑定到特定的控件。最简单的办法就是在控件元素中添加 xsi:type 属性。比如,

<xforms:input ref="Expiration" xsi:type="xs:date"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <xforms:label>Expiration date:</xforms:label>
</xforms:input>

也可以将 xsi:type 属性放在模型中对应的元素上,如 清单 7 所示。这种情况下,该属性将用于绑定到该元素的所有控件。

清单 7. date 类型的 expiration 元素

                <xforms:model
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xforms:instance>
 <CreditCardInfo xmlns="">
 <Name />
 <Number />
 <CVV2 />
 <Expiration xsi:type='xs:date'/>
 <Address1 />
 <Address2 />
 <City />
 <State />
 <Zip />
 </CreditCardInfo>
 </xforms:instance>
 <xforms:submission action="http://example.com/xform-processor" 
 method="post" id="submit" includenamespaceprefixes=""/>
</xforms:model>

最后,还可以在模型中添加 xforms:bind 元素,如清单 8 所示:

清单 8. 将 expiration 元素绑定到 date 类型

                <xforms:model xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xforms:instance>
 <CreditCardInfo xmlns="">
 <Name />
 <Number />
 <CVV2 />
 <Expiration />
 <Address1 />
 <Address2 />
 <City />
 <State />
 <Zip />
 </CreditCardInfo>
 </xforms:instance>
 <xforms:bind nodeset="Expiration" type="xs:date" />
 <xforms:submission action="http://example.com/xform-processor" 
 method="post" id="submit" includenamespaceprefixes=""/>
</xforms:model>

这种绑定的优点是 bind 元素可在 nodeset 属性中用更复杂的 XPath 表达式同时绑定多个输入。

无论使用什么技术,只要 Firefox 具有专门为此种类型设计的控件,则显示这种控件,否则将使用通用的文本字段。这样做的目的是让浏览器实现更复杂的功能,同时表单在不很先进的浏览器中不会被破坏。





回页首


样式

到目前为止表单还非常粗糙。可以用 CSS 和 HTML 进行美化。清单 9 是一个简单的 CSS 样式表,它让标签字体变得更美观,并对齐表单字段使其更整齐。

.xf-value

这里使用的 .xf-value 选择器设置的是输入字段值而非标签的样式。这实际上和当前的 CSS3 草案是不一致的。该例实际上应该使用 ::value 伪类:

input::value { width: 20em; }
#ccnumber::value { width: 18em }
#zip::value { width: 12em }
#state::value { width: 3em }

但是 Firefox 还不支持这种语法。

清单 9. 信用卡表单的 CSS 样式表

                @namespace xforms url("http://www.w3.org/2002/xforms");

xforms|label {
 font-family: Helvetica, Geneva, Lucida, sans-serif;
 font-weight: bold;
 width: 32ex;
 text-align: right;
 padding-right: 1em;
 padding-bottom: 0.8ex;
}

xforms|input, xforms|select1, xforms|submit {
 display: table-row;
}

xforms|input xforms|label, xforms|select1 xforms|label {
 display: table-cell; 
}

.xf-value { width: 20em; }

#ccnumber .xf-value { width: 18em }
#zip .xf-value { width: 12em }
#state .xf-value { width: 3em }

/* color invalid data red */
*:invalid {
 background-color: red;
}

结果网页如 图 7 所示。


图 7. 设置样式后的表单
有效期:日历

图 7 仍然比不上现在某些网站上看到的精心设计的 HTML 表单那么漂亮。但是这纯粹是因为我个人的能力不够。我是一位作家和程序员而不是平面设计师。如果把这个表单交给一位具有 CSS 经验的设计师,很容易就能创造出更吸引人的布局。事实上,对于设计师来说,使用 XForms 比 HTML 表单更方便,因为 XForms 没有任何预定义的呈现语义。所有格式都能用 CSS 定义。就个人而言,如果不用表格布局的话我还从未做出这么好看的 HTML 表单。相比而言,编写这个样式表我只花了大约十五分钟。可以设想一位真正的设计师能够做到什么程度。

这种关注点的分离是 XForms、XML 和一般标记共有的一大优点。设计师可以处理布局和格式,甚至不用接触实际的 XHTML 和 XForms 代码。页面的作者可以把精力集中到内容上,而不用担心显示的结果。双方都能做自己最擅长的事情,不用削足适履。这种分离也意味着他们能够全速工作,不用锁定文件或者互相等待。





回页首


局限

Mozilla XForms 插件支持 XForms 1.0 的大部分和这里讨论的所有特性。不过它还不完整。当前最突出的一些不足包括:

  • XForms 只能内嵌在 XHTML 文档中,媒体类型只能是 application/xhtml+xml。也可以嵌入到其他类型的 XML 文档中。但是无论 HTML 文档中的 XForms 还是 XHTML 文档中的 XForms 都不支持 text/html 媒体类型。
  • 表单只能提交回最初下载表单的服务器。不能把表单提交到其他服务器。
  • Range 控件存在缺陷,经常不工作。
  • Firefox 不支持 CSS3 伪元素 ::value::repeat-item::repeat-index。必须使用 Mozilla 专用扩展 xf-valuexf-repeat-itemxf-repeat-index。如果喜欢的话可以同时使用,这样在 Mozilla 和非 Mozilla 浏览器中都能看到很好的效果。
  • 验证错误信息太少,几乎可以说没有。对模式的支持很可能迷惑用户,因为表单失败没有任何提示也不说明到底哪里出错了。目前只能在服务器上进行验证。

等到 1.0 版发布的时候,这个插件应该会完全支持 XForms 1.0,可能还支持 CSS3。





回页首


结束语

分享此文……

digg 提交到 Digg
del.icio.us 发布到 del.icio.us
Slashdot 提交到 Slashdot!

相比传统的 HTML 表单,XForms 不仅是一种设计和布局表单的更强大的方式,而且更容易使用。由于内容和表示分离,能够更充分地使用 CSS。此外,还能将表单元素放在页面中的任何位置,与其他标记混合在一起。最后,需要大量 JavaScript 代码的表单技巧,比如当用户向一个字段中输入数据时更新另一个字段,在 XForms 中只需要很少的声明性代码。

本文仅仅稍稍分析了一下 XForms 的强大功能。希望这些内容对帮助您入门来说足够了。 XForms 不同于传统的 HTML 表单,学习起来不是很简单。但学习曲线也不是很陡,最简单的办法就是直接在 Web 浏览器中编写和测试表单。Firefox 及 Mozilla XForms 插件都是免费的,并且易于使用。

在 XForms 更广泛的部署到浏览器中之前,客户端 XForms 处理不大可能用于面对公众的网站。但这并不意味着现在不能部署到内网上。如果已经在使用 Firefox(没有的话建议试一试),只需安装一个简单的插件。然后就能充分利用 XForms 的强大、快速和灵活的好处了。



参考资料

学习

获得产品和技术
  • Mozilla XForms Project 编写本文中所述的插件。网站上提供的文档说明了当前不符合规范的地方。这些问题将在 1.0 前解决。

  • 使用 IBM 试用版软件 构建您的下一个开发项目,可直接从 developerWorks 下载。

  • 下载 MozzIE,这种开放源代码的控件可在 IE 中呈现 XForms。

讨论


关于作者

Photo of Elliot Rusty Harold

Elliotte Harold 出生在新奥尔良,现在他还定期回老家喝一碗美味的秋葵汤。但目前他和妻子 Beth、他们的狗 Shayna、猫 Charm 和 Marjorie 定居在布鲁克林附近的 Prospect Heights。他是 Polytechnic 大学的计算机科学副教授,讲授 Java 和面向对象编程。他的 Cafe au Lait Web 站点是 Internet 上最受欢迎的独立 Java 站点之一,子站点 Cafe con Leche 是最受欢迎的 XML 站点之一。他的著作包括 Effective XML Processing XML with Java Java Network Programming The XML 1.1 Bible 。他的最新著作是 Java I/O, 第二版。他目前从事 XOM API 处理 XML、Jaxen XPath 引擎和 Jester 测试覆盖工具的研究。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?




回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款