XQuery/简单 XForms 示例
外观
< XQuery
虽然静态 XForms 可以保存在 eXist 数据库中,但 XForms 也可以使用 XQuery 动态生成。在本节中,我们首先展示静态表单被一些 XForms 客户端引擎输出和执行,这些引擎包括 Firefox 插件、Javascript FormFaces 以及 XSLT/Javascript XSLTForms。
然后我们看看动态表单生成。
可以在 XForms 维基教科书 中找到各种各样的 XForms 示例。
这些示例使用
- Firefox 插件
- 需要带有 XForms 插件的 Firefox
- 媒体类型设置为 application/xhtml+xml
- FormFaces
- 跨浏览器支持 - 示例在 Firefox 和 IE6 上测试
- Javascript 源代码存储在 eXist 数据库中,并链接到每个表单
- 媒体类型设置为 text/html
- XSLTForms
- 使用 XSLT 转换为 HTML 页面,并使用 JavaScript 执行。
- XSLT 转换可以是服务器端(通过 eXist)或客户端端。
所有示例都使用相同的 css 样式表
declare option exist:serialize "method=xhtml media-type=application/xhtml+xml indent=yes";
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:form="http://www.w3.org/2002/xforms" xml:lang="en">
<head>
<title>Output a Model value</title>
<form:model>
<form:instance>
<data xmlns="">
<name>Mozilla XForms add-in</name>
</data>
</form:instance>
</form:model>
</head>
<body>
<h2>
<form:output ref="name"></form:output>
</h2>
</body>
</html>
declare option exist:serialize "method=xhtml media-type=text/html indent=yes"; <html xmlns="http://www.w3.org/1999/xhtml" xmlns:form="http://www.w3.org/2002/xforms" xml:lang="en"> <head> <title>Output a Model value</title> <script language="javascript" src="../formfaces/formfaces.js"/> <link rel="stylesheet" type="text/css" href="xforms.css" /> <form:model> <form:instance> <data xmlns=""> <name>Formfaces</name> </data> </form:instance> </form:model> </head> <body> <h2> <form:output ref="name"></form:output> </h2> </body> </html>
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="ajaxforms.xsl" type="text/xsl"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:form="http://www.w3.org/2002/xforms" xml:lang="en">
<head>
<title>Output a Model value</title>
<script language="javascript" src="formfaces.js"/>
<link rel="stylesheet" type="text/css" href="xforms.css" />
<form:model>
<form:instance>
<data xmlns="">
<name>Formfaces</name>
</data>
</form:instance>
</form:model>
</head>
<body>
<h2>
<form:output ref="name"></form:output>
</h2>
</body>
</html>
- FormFaces : 在 Firefox 上中断
- XSLTForms : 仅在触发时进行更改
一个模型可以包含多个实例,这些实例的根节点可以通过 instance(id) 结构访问。
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
<title>Test conditional selection lists</title>
<xf:model>
<xf:instance id="data" xmlns="">
<data>
<selected-season>spring</selected-season>
<selected-month>March</selected-month>
</data>
</xf:instance>
<xf:instance id="seasons" xmlns="">
<seasons>
<item name="winter"/>
<item name="spring"/>
<item name="summer"/>
<item name="autumn"/>
</seasons>
</xf:instance>
<xf:instance id="months" xmlns="">
<months>
<item name="January" season="winter"/>
<item name="February" season="winter"/>
<item name="March" season="spring"/>
<item name="April" season="spring"/>
<item name="May" season="spring"/>
<item name="June" season="summer"/>
<item name="July" season="summer"/>
<item name="August" season="summer"/>
<item name="September" season="autumn"/>
<item name="October" season="autumn"/>
<item name="November" season="autumn"/>
<item name="December" season="winter"/>
</months>
</xf:instance>
</xf:model>
</head>
<body>
<p>Test conditional selection lists -
month selector depends on the current season</p>
<div>
<xf:select1 ref="instance('data')/selected-season">
<xf:label>Season:</xf:label>
<xf:itemset nodeset="instance('seasons')/item">
<xf:label ref="@name"/>
<xf:value ref="@name"/>
</xf:itemset>
</xf:select1>
</div>
<div>
<xf:select1 ref="instance('data')/selected-month">
<xf:label>Month:</xf:label>
<xf:itemset nodeset="instance('months')/item[@season=instance('data')/selected-season]">
<xf:label ref="@name"/>
<xf:value ref="@name"/>
</xf:itemset>
</xf:select1>
</div>
<div>
<xf:output ref="instance('data')/selected-season">
<xf:label>selected-season: </xf:label>
</xf:output>
<xf:output ref="instance('data')/selected-month">
<xf:label>selected-month: </xf:label>
</xf:output>
</div>
</body>
</html>
- Firefox 生成一个下拉日历。 Firefox
- Formfaces 目前没有日历小部件 Formfaces
与服务器的交互可以通过 GET 或 POST 进行。此示例基于 Dan McCreary 在 XForms 维基教科书 中的示例。
在 Firefox 上
<html xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns="http://www.w3.org/1999/xhtml"> <head> <title>XQuery Tester</title> <link rel="stylesheet" type="text/css" href="xforms.css" /> <xf:model> <xf:instance> <data xmlns=""> <input> <arg1>123</arg1> <arg2>456</arg2> </input> <result> <sum>0</sum> </result> </data> </xf:instance> <xf:submission id="get-instance" method="get" replace="instance" action="adderGet.xq" separator="&"> </xf:submission> <xf:submission id="post-instance" method="post" replace="instance" action="adderPost.xq"> </xf:submission> </xf:model> </head> <body> <h1>XForm interaction with XQuery</h1> <xf:input ref="input/arg1" incremental="true"> <xf:label>Arg1:</xf:label> </xf:input> <br/> <xf:input ref="input/arg2" incremental="true"> <xf:label>Arg2:</xf:label> </xf:input> <br/> <xf:output ref="result/sum"> <xf:label> Sum:</xf:label> </xf:output> <br/> <xf:submit submission="get-instance"> <xf:label>Get</xf:label> </xf:submit> <xf:submit submission="post-instance"> <xf:label>Post</xf:label> </xf:submit> <p id="status"></p> </body> </html>
相应的服务器脚本是
- GET
xquery version "1.0"; declare namespace request="http://exist-db.org/xquery/request"; let $arg1 := number(request:get-parameter("arg1", "0")) let $arg2 := number(request:get-parameter("arg2", "0")) return <data xmlns=""> <input> <arg1>{$arg1}</arg1> <arg2>{$arg2}</arg2> </input> <result> <sum>{$arg1+$arg2}</sum> </result> </data>
- POST
xquery version "1.0"; declare namespace request="http://exist-db.org/xquery/request"; let $data := request:get-data() let $arg1 := number($data/arg1) let $arg2 := number($data/arg2) return <data xmlns=""> <input> <arg1>{$arg1}</arg1> <arg2>{$arg2}</arg2> </input> <result> <sum>{$arg1+$arg2}</sum> </result> </data>
在此示例中,整个模型都会被更新并返回给客户端。或者,可以更新模型的一部分(待续)
此脚本基于 XForms 维基教科书中的一个示例,说明了通用 XForms 的一种简单方法。
declare option exist:serialize "method=xhtml media-type=application/xhtml+xml indent=yes"; let $data := <Data> <GivenName>John</GivenName> <MiddleName>George</MiddleName> <Surname>Doe</Surname> <CityName>Anytown</CityName> <StateCode>MM</StateCode> <PostalID>55123-1234</PostalID> </Data> return <html xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Formatting XForms</title> <link rel="stylesheet" type="text/css" href="xforms.css" /> <style type="text/css"> { for $item in $data/* let $width := string-length($item) return concat('._',name($item),' .xf-value {width:', $width,'em} ') } </style> <xf:model> <xf:instance xmlns=""> {$data} </xf:instance> </xf:model> </head> <body> <fieldset> <legend>Name and Address</legend> {for $item in $data/* return ( <xf:input class="_{name($item)}" ref="/Data/{name($item)}"> <xf:label>{name($item)}: </xf:label> </xf:input>, <br/> ) } </fieldset> </body> </html>
在这个简单的表格示例中,XForm 和用于定义输入字段宽度的配套 CSS 是通过对提供的实例进行反射生成的。
此示例在 Firefox 中正常工作,但在 Formfaces 中样式失败
一个简单的架构可以提供对生成的 XForms 的更多控制。此示例仍然用于简单的表格结构
declare option exist:serialize "method=xhtml media-type=application/xhtml+xml indent=yes"; let $data := <Data> <GivenName>John</GivenName> <MiddleName>George</MiddleName> <Surname>Doe</Surname> <CityName>Anytown</CityName> <StateCode>MM</StateCode> <PostalID>55123-1234</PostalID> </Data> let $schema := <Schema> <Row name="GivenName" label="First Name" width="20"/> <Row name="Surname" label="Surname" width="15"/> <Row name="CityName" label="City" width="15"/> <Row name="StateCode" label="State" width="3"/> <Row name="PostalID" label="ZipCode" width="8"/> </Schema> return <html xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Formatting XForms</title> <link rel="stylesheet" type="text/css" href="xforms.css" /> <style type="text/css"> { for $item in $schema/* let $id := concat("_",$item/@name) let $width := $item/@width return concat('.',$id,' .xf-value {width:', $width,'em} ') } </style> <xf:model> <xf:instance xmlns=""> {$data} </xf:instance> </xf:model> </head> <body> <fieldset> <legend>Name and Address</legend> {for $item in $schema/* let $id := concat("_",$item/@name) let $label := string( $item/@label) return ( <xf:input class="{$id}" ref="/Data/{$item/@name}"> <xf:label>{$label}: </xf:label> </xf:input>, <br/> ) } </fieldset> </body> </html>