跳至内容

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 需要与表单本身位于同一个主机上。[需要对此说法进行测试和经验性确认。]

更多信息

[编辑 | 编辑源代码]
华夏公益教科书