XSLT转换如何将输入文件中的注释行保留输出到结果文件
问题原因
你当前的脚本无法处理注释内条目有两个核心原因:
- 生成目录列表时,
apply-templates仅选择了正常的s9ml:exhibit元素节点,完全没有覆盖XML注释节点 - XSLT默认没有针对注释节点的自定义处理逻辑,即使选中注释也不会按你的业务规则解析、转换内容
修改方案
你使用的是XSLT 3.0,可直接用内置的XML片段解析能力处理注释内容,修改点共3处:
- 调整目录区域的节点选择逻辑,同时选中正常的exhibit节点和注释节点,保证输出顺序和源文件顺序完全一致
- 新增注释节点匹配模板,提取注释内的XML文本,解析为节点后复用你已有的exhibit处理逻辑生成对应HTML结构
- 将注释内条目生成的HTML结构用XHTML注释包裹,保持注释状态
修改后完整脚本
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:s9ml="http://www.standardnine.com/s9ml" exclude-result-prefixes="xs math xd xhtml s9ml" xmlns:epub="http://www.idpf.org/2007/ops" version="3.0"> <xsl:output method="xhtml"/> <xsl:param name="topicPrefix"/> <xsl:template match="/"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title><xsl:apply-templates select="//s9ml:metadata/s9ml:title"/></title> <link rel="stylesheet" type="text/css" href="../css/epub-spec.css" /> </head> <body> <ol class="toc"> <!-- 替换原来的选择逻辑,按文档顺序同时选中exhibit和注释节点 --> <xsl:apply-templates select="//s9ml:spine/descendant::node()[self::s9ml:exhibit or self::comment()]"/> </ol> </body> </html> </xsl:template> <!-- 处理注释节点 --> <xsl:template match="comment()"> <xsl:variable name="commentContent" select="normalize-space(.)"/> <!-- 仅处理包含exhibit条目的注释,其他无关注释直接忽略 --> <xsl:if test="contains($commentContent, 'exhibit')"> <xsl:comment> <!-- 解析注释内的XML片段,复用exhibit处理模板 --> <xsl:apply-templates select="parse-xml-fragment($commentContent)//*:exhibit"/> </xsl:comment> </xsl:if> </xsl:template> <!-- process exhibits referenced from toc.s9ml --> <xsl:template match="s9ml:exhibit"> <xsl:element name="li" namespace="http://www.w3.org/1999/xhtml"> <xsl:variable name="count" select="position()"/> <xsl:attribute name="id"> <xsl:value-of select="$topicPrefix"/> <xsl:number format="0000" level="any"/> </xsl:attribute> <xsl:element name="a" namespace="http://www.w3.org/1999/xhtml"> <xsl:attribute name="href"> <xsl:value-of select="@path" /> </xsl:attribute> <xsl:apply-templates select="document(@path)//xhtml:title"/> </xsl:element> </xsl:element> </xsl:template> </xsl:stylesheet>
效果说明
- 源文件中未注释的exhibit条目会按原有逻辑生成带ID、跳转链接的li节点,和之前的输出完全一致
- 源文件中注释包裹的exhibit条目,会走完全相同的转换逻辑生成对应li节点,最终整体被包裹在XHTML注释中插入到对应位置,保持注释状态
- 所有条目顺序和源文件中的先后顺序完全一致,不会出现错位
如果你不需要注释内的条目生成ID属性,可在注释模板里调用exhibit模板时传入参数控制编号逻辑,按需调整即可。
内容的提问来源于stack exchange,提问作者pantherfan
相关产品推荐
相关产品推荐

