如何让XSLT仅在匹配指定QID列表的文件上运行?
解决方案:让XSLT仅在匹配指定QID的文档中执行修改
你的需求是让XSLT只在包含指定QID(匹配span[data-value]字段)的文档中执行自定义修改,否则保持文档原样。现有代码的问题是没有添加条件判断,导致不管文档是否匹配QID都会执行移除p.atom-exclude类的操作。下面是调整后的完整实现:
修改后的XSLT脚本
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.w3.org/1999/xhtml"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <!-- 输入QID列表,多个QID用空格分隔 --> <xsl:param name="QIDlist">NCQ0264</xsl:param> <!-- 将QID列表拆分为单个QID的序列 --> <xsl:variable name="input-qid" select="tokenize($QIDlist, '\s+')"/> <!-- 检查当前文档是否存在匹配的QID元素 --> <xsl:variable name="has-matching-qid" select="exists(//span[@property='atom:content-item-name' and @class='ktp-meta' and @data-value = $input-qid])"/> <!-- 根节点处理:如果没有匹配QID,直接原样输出文档;否则执行正常转换 --> <xsl:template match="/"> <xsl:choose> <xsl:when test="$has-matching-qid"> <xsl:apply-templates/> </xsl:when> <xsl:otherwise> <xsl:copy-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- 恒等转换:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 仅当存在匹配QID时,移除p元素的atom-exclude类 --> <xsl:template match="p/@class[.='atom-exclude']" priority="1"> <!-- 空模板,不输出该属性,实现移除效果 --> </xsl:template> </xsl:stylesheet>
关键调整说明
- 添加匹配检查变量:
$has-matching-qid通过exists()函数判断当前文档中是否存在符合条件的span元素——即带有property="atom:content-item-name"、class="ktp-meta"且data-value在输入QID列表中的元素。 - 根节点条件处理:如果没有匹配的QID,直接用
<xsl:copy-of select="."/>原样输出整个文档,跳过所有自定义转换逻辑;如果有匹配,则正常执行后续模板。 - 限定自定义模板生效范围:移除
p.atom-exclude类的模板保留了priority="1",确保它比默认的恒等转换模板优先匹配,同时只有在$has-matching-qid为真时才会实际生效(因为根节点已经控制了是否应用该模板)。
额外说明
- 如果需要支持多个QID,只需在
$QIDlist参数中用空格分隔多个值即可,比如NCQ0264 NCQ0265 NCQ0266。 - 如果你希望仅针对匹配QID的元素所在的局部区域执行修改,而不是整个文档,可以进一步调整模板的匹配条件,比如限定只处理该
span元素所在的父容器内的p元素。
内容的提问来源于stack exchange,提问作者mjwolff1
相关产品推荐
相关产品推荐

