多XSLT文件合并为单文件执行时mode模式标识转换输出异常求解
故障原因
你当前的XSLT缺少phase1模式下的默认身份转换规则:
- 仅定义了默认模式的身份转换模板,
<a>、<b>、<f>等非<c>节点在phase1模式下无匹配模板,会触发XSLT内置默认处理规则 - 内置规则对元素节点会跳过标签本身直接递归处理子内容,对文本节点直接输出值,因此会出现标签丢失、仅保留内部文本的问题
修复方案
方案1(XSLT 3.0 推荐)
直接新增xsl:mode声明,指定phase1模式下未匹配到的节点默认执行复制操作,代码最简洁:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <!-- 新增配置:phase1模式下未匹配节点默认执行浅复制 --> <xsl:mode name="phase1" on-no-match="shallow-copy"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="phase1"/> </xsl:copy> </xsl:template> <xsl:template match="c" mode="phase1"> <xsl:copy-of select="."/> <generator> <xsl:iterate select="./d"> <test> <xsl:value-of select="." /> </test> </xsl:iterate> </generator> </xsl:template> </xsl:stylesheet>
方案2(兼容低版本XSLT)
手动新增phase1模式的身份转换模板,不需要依赖3.0的新特性:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <!-- 默认模式身份转换 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="phase1"/> </xsl:copy> </xsl:template> <!-- 新增:phase1模式身份转换 --> <xsl:template match="@*|node()" mode="phase1"> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="phase1"/> </xsl:copy> </xsl:template> <xsl:template match="c" mode="phase1"> <xsl:copy-of select="."/> <generator> <xsl:for-each select="./d"> <test> <xsl:value-of select="." /> </test> </xsl:for-each> </generator> </xsl:template> </xsl:stylesheet>
注:低版本XSLT不支持xsl:iterate,替换为xsl:for-each即可实现相同效果。
内容的提问来源于stack exchange,提问作者Sai Prasad Mukthapuram
相关产品推荐
相关产品推荐

