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))
<= (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;在表单中包含它们的文本两次没有问题。为了实现这一点,我们必须
- 创建一个包含后退按钮、位置消息和前进按钮的 XML 文档。我们将这三个元素包装在一个 XHTML
div
元素中,以使 XML 具有单个根元素,并将结果文件命名为 "FBButtons.xhtml"。 - 在主表单中的适当位置,使用
xf:include
元素,并设置适当的src
值。如果 "FBButtons.xhtml" 与主表单位于同一目录中,我们将使用<xf:include src="FBButtons.xhtml"/>
。
xf:include
元素按主 XForm 中指定的方式工作,并在通过xf:include
加载的文档中递归工作。在子表单中,子表单是在稍后加载的,它在某些浏览器中有效,而在另一些浏览器中无效(包括基于 Webkit 的浏览器)。这种差异的原因是某些浏览器不愿意评估从 Javascript 调用的 XSLT 样式表中的 XSLTdocument()
函数,这是由于某种安全问题。
- 浏览器将强制实施同源策略,这意味着指向要包含的 XML 文档的绝对 URI 需要与表单本身位于同一个主机上。[需要对此说法进行测试和经验性确认。]
- Alain Couthures 给 xsltforms-support 列表的邮件,2016 年 7 月 3 日,解释了在子表单中使用
xf:include
的问题。 - 示例表单,展示了在主表单和动态加载的子表单中使用
xf:include
的方法;后者不起作用。