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>