跳到內容

XForms/從檔案中選擇程式碼

來自 Wikibooks,開放的書籍,開放的世界
最佳實踐

設計表單的人員經常需要維護許多程式碼表。這些程式碼表可能會經常更改,並且可能存在更新中心維護的程式碼表資料庫的流程。因此,您希望每個表單都能夠動態地從 XML 檔案或 RESTful 網路服務中獲取當前相關的程式碼。

此示例程式演示瞭如何直接從檔案或程式碼表網路服務中讀取帶標籤的程式碼列表。在此示例中,包含程式碼的檔案只是一個格式良好的 XML 檔案,它位於與表單相同的目錄中。

從本地檔案或網路服務載入 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 資料

[編輯 | 編輯原始碼]
<?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 檔案必須包含一個根資料元素,該元素必須與節點集引數匹配。

從 XML REST 網路服務中提取資料

[編輯 | 編輯原始碼]

您可以將例項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

[編輯 | 編輯原始碼]

將資料載入到模型後,每個select1select控制元件都可以使用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 不包含表示資訊,因此我們使用以下工作流作為“最佳實踐”。

  1. 將所有標籤/值對儲存在外部程式碼表檔案中,或從網路服務中獲取此資訊。
  2. 對於每個表單,建立一個網路服務,該服務將為表單中使用的所有程式碼生成程式碼表元素。
  3. 將程式碼表元素載入到模型中的一個單獨的例項中,並將其 ID 設定為“code-tables”。
  4. 透過獲取具有該名稱的程式碼表來從該例項中選擇每個 select1 或 select 元素的程式碼表。

當需要將一組共享通用程式碼的複雜表單放置在自己的目錄中,並且仍然連結到程式碼的中心目錄時,您也可以使用相對程式碼表連結。例如,一個兄弟目錄可以稱為“code-tables”,並且可以將 src="MyCode.xml" 語句修改為 src="../code-tables/MyCode.xml"。

如果您有表單的 XML Schema,您還可以提取每個 simpleType 的所有列舉列表。然後,可以將此程式碼列表傳遞給建立一個登錄檔中所有程式碼列表的網路服務。這允許在 XML Schema 中新增新程式碼時自動更新表單。

如果您有一個包含所有表單程式碼的 RESTful 網路服務,您可以用該網路服務的 URI 替換此 XML 檔案。

下一頁: 選擇日期 | 上一頁: 從模型中選擇
首頁: XForms
華夏公益教科書