跳至內容

XSLTForms/include

來自華夏公益教科書,自由的教學讀物

xf:include 元素在編譯時將外部檔案包含到表單中,在 xsltforms.xsl 樣式表評估期間。因此,它的功能類似於 XML 中的通用實體或 XInclude xi:include 元素。

它可用於減少表單中多個點處的程式碼重複,在表單之間共享程式碼,或僅僅將子表單的複雜部分移到單獨的文件中,以使主表單的邏輯更清晰,更容易理解。

xf:include 元素為空。它只帶有一個屬性:src

src 屬性的值是 URI 引用(絕對或相對),指向要包含在表單中的 XML 文件。

表單內的重複程式碼

[編輯 | 編輯原始碼]

考慮一個 XForm,它接受使用者的查詢資料,向後端搜尋引擎提交查詢,並將結果顯示給使用者。為了避免使用者瀏覽器和/或網路的過載,我們希望在任何時候只向用戶傳送一頁結果,並允許使用者分頁瀏覽結果,每次顯示那麼多結果。

這種表單的總體結構可能類似於這樣;我們假設一個名為 query 的例項來儲存查詢字串和結果中的起始位置,以及一個名為 results 的例項來儲存結果。

<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:xf="http://www.w3.org/2002/xforms"
      xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
    ...
</head>
<body>
    <h2>Query tool</h2>

    ... controls for query string, submission ...

    <xf:group ref="instance('results')/self::result[.//hits]">

        ... code for Back and Forward buttons ... 

        <xf:repeat nodeset="self::test//hits/hit">
            ... display one hit ...
        </xf:repeat>

        ... code for Back and Forward buttons ...
      
    </xf:group>
</body>
</html>

為了減少結果頁面中上下滾動所需的次數,我們希望在結果列表的頂部和底部都有按鈕,用於向前和向後移動結果。這兩個按鈕的程式碼將是相同的:首先是一個後退按鈕,它只在當前起始位置大於 1 時顯示

<xf:group ref=".[instance('query')/startpos > 1]">
    <xf:trigger>
        <xf:label>Back</xf:label>
        <xf:action ev:event="DOMActivate">
            <xf:setvalue ref="instance('query')/startpos" 
                value="instance('query')/startpos - instance('query')/pagesize "/>
            <xf:send submission="send-query"/>
        </xf:action>
    </xf:trigger>
</xf:group>

然後是一個訊息,指示結果中的位置(例如,“34 個結果中的第 11 到 20 個”,或“無結果”)

<xf:group ref=".[.//hits/@n > 0][.//hit]">
    <p>Results <xf:output ref=".//hit[1]/@n"/>
        to <xf:output value=".//hit[last()]/@n"/>
        of <xf:output value="instance('results')//hits/@n"/>
    </p>
</xf:group>
<xf:group ref=".[.//hits/@n = 0]">
    <p>No results.</p>
</xf:group>

最後是一個前進按鈕,它只在當前未顯示最後一條命中時顯示

<xf:group ref=".[(instance('query')/startpos + count(.//hit)) 
               &lt;= (self::test/results/hits/@n)]">  
    <xf:trigger>
        <xf:label>Forward</xf:label>
        <xf:action ev:event="DOMActivate">
            <xf:setvalue ref="instance('query')/startpos" 
                value="instance('query')/startpos + instance('query')/pagesize"/>
            <xf:send submission="send-query"/>
        </xf:action>
    </xf:trigger>
</xf:group>

注意,前進和後退按鈕以及當前位置訊息沒有需要唯一的 ID;在表單中包含它們的文字兩次沒有問題。為了實現這一點,我們必須

  1. 建立一個包含後退按鈕、位置訊息和前進按鈕的 XML 文件。我們將這三個元素包裝在一個 XHTML div 元素中,以使 XML 具有單個根元素,並將結果檔案命名為 "FBButtons.xhtml"。
  2. 在主表單中的適當位置,使用 xf:include 元素,並設定適當的 src 值。如果 "FBButtons.xhtml" 與主表單位於同一目錄中,我們將使用 <xf:include src="FBButtons.xhtml"/>

已知問題和問題

[編輯 | 編輯原始碼]
  • xf:include 元素按主 XForm 中指定的方式工作,並在透過 xf:include 載入的文件中遞迴工作。在子表單中,子表單是在稍後載入的,它在某些瀏覽器中有效,而在另一些瀏覽器中無效(包括基於 Webkit 的瀏覽器)。這種差異的原因是某些瀏覽器不願意評估從 Javascript 呼叫的 XSLT 樣式表中的 XSLT document() 函式,這是由於某種安全問題。
  • 瀏覽器將強制實施同源策略,這意味著指向要包含的 XML 文件的絕對 URI 需要與表單本身位於同一個主機上。[需要對此說法進行測試和經驗性確認。]

更多資訊

[編輯 | 編輯原始碼]
華夏公益教科書