如何从XML源文档设置任意样式表参数?DocBook文档场景
问题解答
1. 仅使用XSLT能否实现该需求?
可以实现,但不能通过动态定义<xsl:param>的方式——XSLT是静态编译型语言,参数名称必须在编译阶段确定,无法用变量动态生成参数名。
可行的思路是:
- 先遍历整个文档,收集所有
xslt-param处理指令中的参数名和值,存入一个全局的键值映射(XSLT 2.0+可用map,旧版本可用节点集) - 在需要使用参数的模板或逻辑中,优先从这个映射中取值;如果映射中没有对应键,再使用样式表的默认参数值
示例代码片段(XSLT 2.0+):
<!-- 全局变量:收集所有xslt-param处理指令的参数 --> <xsl:variable name="doc-params" as="map(xs:string, xs:string)"> <xsl:map> <xsl:for-each select="//processing-instruction('xslt-param')"> <xsl:variable name="name" select="tokenize(., '\s+')[starts-with(., 'name=')]"/> <xsl:variable name="value" select="tokenize(., '\s+')[starts-with(., 'value=')]"/> <xsl:map-entry key="replace($name, 'name="?([^"]+)"?', '$1')" select="replace($value, 'value="?([^"]+)"?', '$1')"/> </xsl:for-each> </xsl:map> </xsl:variable> <!-- 使用参数时的逻辑:优先用文档内定义的值,否则用默认参数 --> <xsl:template match="section"> <xsl:variable name="autolabel" select="if (map:contains($doc-params, 'section.autolabel')) then map:get($doc-params, 'section.autolabel') else $section.autolabel"/> <!-- 后续渲染逻辑使用$autolabel变量 --> </xsl:template>
2. DocBook XSL 1.79.2中除dbfo外的其他方法?
除了专门的dbfo处理指令,还有几种替代方案:
自定义元数据元素:在文档的
<articleinfo>或自定义的元数据节点中添加参数配置,比如:<article> <articleinfo> <custom-params> <param name="section.autolabel" value="1"/> </custom-params> </articleinfo> <!-- 文档内容 --> </article>然后在样式表中读取这个节点的值,覆盖默认参数。
顶层样式表参数覆盖:编写一个自定义的入口样式表,先导入DocBook PDF样式表,然后在
<xsl:param>的select属性中添加逻辑,从文档中提取参数值:<xsl:import href="docbook-xsl/pdf/docbook.xsl"/> <xsl:param name="section.autolabel" select=" if (//processing-instruction('xslt-param')[contains(., 'name="section.autolabel"')]) then replace(//processing-instruction('xslt-param')[contains(., 'name="section.autolabel"')], '.*value="?([^"]+)"?.*', '$1') else '0'"/>复用DocBook的pi-attribute模板:你之前尝试的模板可以调整为收集参数,而非定义参数,结合全局变量使用,避免动态参数名的问题。
3. 是否有XSLT处理器提供此类功能的扩展?
主流处理器中,**Saxon(包括HE版本)**可以通过XSLT 2.0/3.0的原生特性实现类似功能,无需额外扩展:
- 用XSLT 2.0的
map(或XSLT 1.0的节点集)存储文档内定义的参数 - 用XPath的字符串处理函数提取处理指令中的键值对
如果使用Saxon PE/EE版本,还可以利用扩展函数或动态求值功能,但HE版本的原生特性已经足够满足需求。其他处理器如Xalan也可以通过节点集的方式实现类似的参数收集逻辑。
内容的提问来源于stack exchange,提问作者Paul A. Hoadley
相关产品推荐
相关产品推荐

