如何修改XSLT实现不匹配section/@id的xref标签注释化?
修正XSLT实现xref标签的注释逻辑
需求明确
当<xref>标签的@href属性值与文档中任意<section>标签的@id属性值不匹配时,将该<xref>标签转为注释,同时保留其内部文本为纯文本;匹配的<xref>标签则正常保留。
输入XML示例
<root> <section id="sec1"> <p>这是第一段内容,包含<xref href="sec2">第二节</xref>和<xref href="invalid">无效链接</xref></p> </section> <section id="sec2"> <p>这是第二段内容,包含<xref href="sec1">第一节</xref></p> </section> </root>
预期输出XML示例
<root> <section id="sec1"> <p>这是第一段内容,包含<xref href="sec2">第二节</xref>和<!-- <xref href="invalid"> -->无效链接<!-- </xref> --></p> </section> <section id="sec2"> <p>这是第二段内容,包含<xref href="sec1">第一节</xref></p> </section> </root>
原XSLT代码(未达预期)
<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> <xsl:template match="xref"> <xsl:if test="not(//section[@id = @href])"> <xsl:comment> <xsl:copy-of select="."/> </xsl:comment> <xsl:value-of select="."/> </xsl:if> </xsl:template> </xsl:stylesheet>
修正后的XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 建立section id的索引,提升匹配效率 --> <xsl:key name="section-by-id" match="section" use="@id"/> <!-- 身份模板:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 专门处理xref标签 --> <xsl:template match="xref"> <!-- 检查是否存在匹配id的section --> <xsl:choose> <!-- 匹配成功:正常保留xref标签 --> <xsl:when test="key('section-by-id', @href)"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:when> <!-- 匹配失败:输出注释+纯文本 --> <xsl:otherwise> <xsl:comment> <xref href="{@href}"> </xsl:comment> <xsl:value-of select="."/> <xsl:comment> </xref> </xsl:comment> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
关键修正点说明
- 添加索引优化:用
<xsl:key>建立section的id索引,比直接用//section遍历整个文档效率更高,尤其是文档较大时。 - 完善分支逻辑:原代码只处理了不匹配的情况,漏掉了匹配成功时需要保留xref标签的逻辑,导致匹配的xref被直接删除。
- 注释格式规范:用实体
<和>替代尖括号,避免注释内容破坏XML结构。
内容的提问来源于stack exchange,提问作者Kita Ansari
相关产品推荐
相关产品推荐

