如何基于XSLT的xsl:copy命令为过滤后的新XML添加注释?
基于xsl:copy实现XML节点过滤与顶部注释添加
完全可以通过xsl:copy为核心的XSLT模板实现你的需求,下面分基础版和进阶版给出具体实现:
基础版实现
核心思路是用身份模板(基于xsl:copy的默认复制逻辑)保留大部分节点,再用空模板过滤GoAway节点,最后在根节点处理时插入指定注释。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份模板:默认复制所有节点、属性和文本内容 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 过滤GoAway节点:匹配后不输出任何内容 --> <xsl:template match="GoAway"/> <!-- 处理根节点:先输出要求的注释,再执行后续复制逻辑 --> <xsl:template match="/"> <xsl:comment>This file does not contain the elements GoAway</xsl:comment> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>
这里的身份模板是整个逻辑的基础,通过xsl:copy复制当前节点,再递归处理子节点和属性;匹配GoAway的空模板会覆盖身份模板的行为,直接过滤掉该节点;根节点模板则先插入指定注释,再触发后续的复制与过滤流程。
进阶版实现
进阶版需要动态获取源文件名和当前日期,我们可以借助XSLT 2.0及以上的内置函数实现,核心逻辑依然基于xsl:copy的身份模板:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份模板:基于xsl:copy的默认复制逻辑 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 过滤GoAway节点 --> <xsl:template match="GoAway"/> <!-- 处理根节点:生成带动态信息的注释 --> <xsl:template match="/"> <!-- 从源文件URI中提取文件名 --> <xsl:variable name="source-name" select="tokenize(base-uri(/), '/')[last()]"/> <!-- 获取并格式化当前日期(YYYY-MM-DD格式) --> <xsl:variable name="current-date" select="format-date(current-date(), '[Y0001]-[M01]-[D01]')"/> <xsl:comment> This file is based on file <xsl:value-of select="$source-name"/>, and on <xsl:value-of select="$current-date"/> the elements GoAway are filtered out </xsl:comment> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>
这段代码中,base-uri()获取源XML的完整路径,tokenize()拆分路径后取最后一段得到文件名;current-date()获取系统当前日期,format-date()将其格式化为标准的年月日格式。注释内容会动态填充这些信息,同时依然依赖xsl:copy的身份模板完成节点复制,配合过滤模板去掉GoAway节点。
内容的提问来源于stack exchange,提问作者Pierre de la Verre
相关产品推荐
相关产品推荐

