XForms/從檔案中選擇程式碼

設計表單的人員經常需要維護許多程式碼表。這些程式碼表可能會經常更改,並且可能存在更新中心維護的程式碼表資料庫的流程。因此,您希望每個表單都能夠動態地從 XML 檔案或 RESTful 網路服務中獲取當前相關的程式碼。
此示例程式演示瞭如何直接從檔案或程式碼表網路服務中讀取帶標籤的程式碼列表。在此示例中,包含程式碼的檔案只是一個格式良好的 XML 檔案,它位於與表單相同的目錄中。
以下程式碼片段,通常位於 HTML 頭部,演示瞭如何使用例項的“src”屬性從與表單相同的目錄中的本地檔案讀取 XML 資料。
<html>
<xf:model>
<xf:instance src="XMLSchemaTypeCode.xml" id="XMLSchemaTypeCode"/>
</xf:model>
</html>
通常使用單個網路服務來載入所有程式碼表。此服務可以傳遞引數,例如程式碼表的名稱以及人員所屬的組。這可以縮短長列表中的選擇列表。
<html>
<xf:model>
<xf:instance id="ApprovalCodes" src="/db/mdr/services/all-codes.xq?code=ApprovalCodes&group=editor"/>
</xf:model>
</html>
將單個程式碼表載入到單個例項中的問題是,您必須對每個程式碼表執行單獨的 HTTP 獲取操作。對於具有一個或兩個小型選擇列表的表單,這不成問題。但是,對於具有許多選擇列表的大型表單,這會減慢表單響應時間。解決方案是透過單個 HTTP GET 請求將所有程式碼載入到單個例項中。然後可以從該例項中選擇每個程式碼表。
<html>
<xf:model>
<xf:instance id="code-tables" src="/db/mdr/services/all-codes.xq?form=DataElementManager&group=admin"/>
</xf:model>
</html>
在第二個示例中,表單中的所有程式碼都由元資料登錄檔 (MDR) 的服務生成。此伺服器返回的資料是表單中每個 select1 控制元件的程式碼集合。
這將查詢當前目錄中的格式良好的 XML 檔案,並將其載入到模型例項中。
請注意,在這種情況下,模型被賦予了 ID。這是為了允許多個程式碼表分別讀入各自的單獨模型。
以下是對程式的螢幕影像。當用戶從下拉列表中選擇時,輸出的值會立即更新。

請注意,螢幕上的標籤與儲存在模型中的標籤不同。
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms" >
<head>
<title>Select List From File</title>
/* the default model */
<xf:model>
<xf:instance id="save-data" xmlns="">
<data>
<MyXMLSchemaTypeCode/>
</data>
</xf:instance>
<xf:instance id="code-tables" src="XMLSchemaTypeCode.xml"/>
</xf:model>
</head>
<body>
<p>This selection list was read from a file.</p>
<xf:select1 ref="/MyData/MyXMLSchemaTypeCode">
<xf:label>Select XML Schema data type: </xf:label>
<xf:itemset ref="instance('code-tables')/XMLSchemaTypeCode/item">
<xf:label ref="label"/>
<xf:value ref="value"/>
</xf:itemset>
</xf:select1>
<br/>
<xf:output ref="instance('save-data')/MyXMLSchemaTypeCode">
<xf:label>Value of MyXMLSchemaTypeCode: </xf:label>
</xf:output>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<XMLSchemaTypeCode>
<label>XML Schema Type:</label>
<item>
<label>Date and Time</label>
<value>dateTime</value>
</item>
<item>
<label>Time (HH:MM:SS-06:00)</label>
<value>time</value>
</item>
<item>
<label>Date (yyyy-mm-dd)</label>
<value>date</value>
</item>
<item>
<label>Year and Month</label>
<value>gYearMonth</value>
</item>
<item>
<label>Year (nnnn)</label>
<value>gYear</value>
</item>
<item>
<label>Month and Day</label>
<value>gMonthDay</value>
</item>
<item>
<label>Day of Month (1 .. 31)</label>
<value>gDay</value>
</item>
<item>
<label>Month (1 .. 12)</label>
<value>gMonth</value>
</item>
<item>
<label>String</label>
<value>string</value>
</item>
<item>
<label>Boolean (true/false)</label>
<value>boolean</value>
</item>
<item>
<label>Base 64 Binary</label>
<value>base64Binary</value>
</item>
<item>
<label>Decimal (0.00)</label>
<value>decimal</value>
</item>
<item>
<label>Any URI</label>
<value>anyURI</value>
</item>
<item>
<label>Integer (...,-2,-1,0,1,2,...)</label>
<value>integer</value>
</item>
<item>
<label>Non-Positive Integer (...,-2,-1,0)</label>
<value>nonPositiveInteger</value>
</item>
<item>
<label>Negative Integer (...,-2,-1)</label>
<value>negativeInteger</value>
</item>
<item>
<label>Long (-9,223,372T .. 9,223,372T)</label>
<value>long</value>
</item>
<item>
<label>Int (-2,147,483,648 .. 2,147,483,647)</label>
<value>int</value>
</item>
<item>
<label>Short (-32,768 .. 32,767)</label>
<value>short</value>
</item>
<item>
<label>Byte (-128 .. 127)</label>
<value>byte</value>
</item>
<item>
<label>Non-negative Integer (0..N)</label>
<value>nonNegativeInteger</value>
</item>
<item>
<label>Positive Integer (1..N)</label>
<value>positiveInteger</value>
</item>
<item>
<label>Unsigned Long (0 .. 18,446,744T)</label>
<value>unsignedLong</value>
</item>
<item>
<label>Unsigned Int (0 .. 4,294,967,295)</label>
<value>unsignedInt</value>
</item>
<item>
<label>Unsigned Short (0.. 65,535)</label>
<value>unsignedShort</value>
</item>
<item>
<label>Unsigned Byte (0..255)</label>
<value>unsignedByte</value>
</item>
</XMLSchemaTypeCode>
請注意,要格式良好,XML 檔案必須包含一個根資料元素,該元素必須與節點集引數匹配。
您可以將例項src屬性替換為指向 XML REST 網路服務的直接路徑。例如,如果您將所有程式碼表都放在專案資源集合中,則路徑看起來如下所示
<xf:instance src="../resources/code-tables/PersonGenderCode.xml"/>
或者,如果您的系統程式碼儲存在單個 XML 檔案中,並且您有一個包裝器 XQuery,則
<xf:instance src="../resources/code-tables/get-codes-for.xq?element=PersonGenderCode"/>
為了使您的表單保持快速,通常最好對所有程式碼執行一次 HTTP GET 操作。如果每個列表都執行單獨的 HTTP GET 操作,則具有許多選擇列表的表單載入時間會很長。對於大型表單,可以輕鬆地將表單載入時間提高 10 倍。
以下是載入到單個例項中的所有程式碼的示例結構
<xf:instance id="code-tables">
<code-tables>
<code-table>
<code-table-name>MyElementCode</code-table-name>
<items>
<item>
<label>Joe Smith</label>
<value>42</value>
</item>
<item>
<label>Sue Johnson</label>
<value>47</value>
</item>
<items>
</code-table>
<code-table>
<code-table-name>ColorCode</code-table-name>
<items>
<item>
<label>Red</label>
<value>1</value>
</item>
<item>
<label>Orange</label>
<value>2</value>
</item>
<items>
</code-table>
</code-tables>
</xf:instance>
將資料載入到模型後,每個select1或select控制元件都可以使用xf:itemset元素直接從模型中獲取資料。Itemset 的工作方式與 repeat 相同,並使用 nodeset(而不是 ref)來獲取所有值。以下是如何從程式碼表例項中獲取 itemset 資料的示例。
<xf:select1 ref="instance('save-data')/MyElementName">
<xf:label>My Element:</xf:label>
<xf:itemset nodeset="instance('code-tables')/code-table[code-table-name='MyElementCode']/items/item">
<xf:label ref="label"/>
<xf:value ref="value"/>
</xf:itemset>
</xf:select1>
請注意,謂詞 [code-table-name='MyElementCode'] 僅將該程式碼的專案放入選擇列表中。
由於 XML Schema 不包含表示資訊,因此我們使用以下工作流作為“最佳實踐”。
- 將所有標籤/值對儲存在外部程式碼表檔案中,或從網路服務中獲取此資訊。
- 對於每個表單,建立一個網路服務,該服務將為表單中使用的所有程式碼生成程式碼表元素。
- 將程式碼表元素載入到模型中的一個單獨的例項中,並將其 ID 設定為“code-tables”。
- 透過獲取具有該名稱的程式碼表來從該例項中選擇每個 select1 或 select 元素的程式碼表。
當需要將一組共享通用程式碼的複雜表單放置在自己的目錄中,並且仍然連結到程式碼的中心目錄時,您也可以使用相對程式碼表連結。例如,一個兄弟目錄可以稱為“code-tables”,並且可以將 src="MyCode.xml" 語句修改為 src="../code-tables/MyCode.xml"。
如果您有表單的 XML Schema,您還可以提取每個 simpleType 的所有列舉列表。然後,可以將此程式碼列表傳遞給建立一個登錄檔中所有程式碼列表的網路服務。這允許在 XML Schema 中新增新程式碼時自動更新表單。
如果您有一個包含所有表單程式碼的 RESTful 網路服務,您可以用該網路服務的 URI 替換此 XML 檔案。