You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT转换如何将输入文件中的注释行保留输出到结果文件

问题原因

你当前的脚本无法处理注释内条目有两个核心原因:

  • 生成目录列表时,apply-templates仅选择了正常的s9ml:exhibit元素节点,完全没有覆盖XML注释节点
  • XSLT默认没有针对注释节点的自定义处理逻辑,即使选中注释也不会按你的业务规则解析、转换内容

修改方案

你使用的是XSLT 3.0,可直接用内置的XML片段解析能力处理注释内容,修改点共3处:

  1. 调整目录区域的节点选择逻辑,同时选中正常的exhibit节点和注释节点,保证输出顺序和源文件顺序完全一致
  2. 新增注释节点匹配模板,提取注释内的XML文本,解析为节点后复用你已有的exhibit处理逻辑生成对应HTML结构
  3. 将注释内条目生成的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:48:26