XSLT转换中如何保留文件集合内的原始文件名?
解决XSLT集合循环中获取原始ID的问题
核心问题分析
你当前用collection('collection.xml')获取的是每个目标XML文档的根节点集合,循环时上下文是这些文档节点,自然没法直接拿到collection.xml里<doc>元素的name属性。要保留原始ID生成文件名并复用,得换一种循环方式——直接遍历collection.xml里的<doc>元素,同时加载对应XML文档。
具体实现方案
1. 先加载collection配置文档
先把collection.xml作为普通XML文档加载,方便后续获取每个<doc>的name和href:
<xsl:variable name="collection-config" select="document('collection.xml')"/>
2. 遍历<doc>元素而非文档集合
循环collection-config里的<doc>节点,这样既能直接拿到@name作为ID,又能通过@href加载对应的XML文档:
<xsl:for-each select="$collection-config/collection/doc"> <!-- 提取当前文档的ID --> <xsl:variable name="doc-id" select="@name"/> <!-- 加载对应的XML文档 --> <xsl:variable name="target-doc" select="document(@href)"/> <!-- 用原始ID生成HTML文件名 --> <xsl:result-document href="{$doc-id}.html" method="html"> <!-- 调用模板时把目标文档节点传过去,保持原有逻辑 --> <xsl:call-template name="separate_page_for_file"> <xsl:with-param name="current-doc" select="$target-doc"/> </xsl:call-template> </xsl:result-document> <!-- 复用ID关联图片等资源 --> <img src="{$doc-id}_0.jpeg" alt="文档{$doc-id}的图片"/> </xsl:for-each>
3. 适配原有模板(可选)
如果你的separate_page_for_file模板原本默认处理当前上下文,需要修改模板接收参数:
<xsl:template name="separate_page_for_file"> <xsl:param name="current-doc"/> <!-- 后续逻辑用$current-doc代替原来的上下文节点即可 --> <html> <body> <h1><xsl:value-of select="$current-doc/title"/></h1> <!-- 其他内容处理 --> </body> </html> </xsl:template>
备选方案(不依赖collection的name属性)
如果没法用name属性,也可以从文档的URI中提取ID(前提是XML文件名和ID一致):
<xsl:for-each select="$my_collection"> <!-- 从文档URI提取文件名,去掉.xml后缀得到ID --> <xsl:variable name="doc-id" select="replace(tokenize(base-uri(.), '/')[last()], '\.xml$', '')"/> <xsl:result-document href="{$doc-id}.html" method="html"> <xsl:call-template name="separate_page_for_file"/> </xsl:result-document> </xsl:for-each>
这种方法不需要修改循环逻辑,但可靠性不如直接用name属性,因为文件名可能和业务ID不匹配。
内容的提问来源于stack exchange,提问作者sleepyhead
相关产品推荐
相关产品推荐

