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>