如何修复XSLT以正确将XML转换为预期HTML格式?
修复XSLT实现XML到HTML的正确顺序转换
你现在遇到的问题是XSLT处理节点的顺序逻辑错误,导致输出内容的顺序和XML原始结构不一致。先把你的场景整理清晰:
你的XML内容:
<PARA> 1050 <EMPH STYLE="min_max"> <EMPH HL="LOW">-50</EMPH> <EMPH HL="HIGH">+50</EMPH> </EMPH> min <EMPH BOLD="0" HL="HIGH" ITAL="0" SMALLCAPS="0">-1</EMPH> </PARA>
期望输出:
1050 -50 +50 min<sup>-1</sup>
当前错误输出:
1050 min -50 +50 <sup>-1</sup>
原XSLT代码:
<xsl:template match="PARA"> <xsl:value-of select="text()"/> <xsl:choose> <xsl:when test="EMPH"> <xsl:apply-templates select="EMPH"/> </xsl:when> </xsl:choose> </xsl:template> <xsl:template match="EMPH"> <xsl:choose> <xsl:when test="@BOLD=1"><b><xsl:value-of select="."/></b></xsl:when> <xsl:when test="@HL='HIGH'"><sup><xsl:value-of select="."/></sup></xsl:when> <xsl:otherwise> <xsl:value-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:template>
问题根源
你的原代码有两个核心问题:
- 节点处理顺序混乱:在
PARA模板里,你先通过<xsl:value-of select="text()"/>一次性取出了所有文本节点(包括" 1050 "和" min "),之后才处理所有EMPH节点。这就导致所有文本内容先被输出,再批量输出EMPH内容,完全打乱了XML里的原始顺序。 - 嵌套EMPH处理失效:当
EMPH节点包含子EMPH节点时(比如那个STYLE="min_max"的EMPH),<xsl:value-of select="."/>只会取出该节点下的所有文本内容,不会递归处理子EMPH的样式规则。
修复后的XSLT代码
<xsl:template match="PARA"> <!-- 严格按XML原始顺序处理所有子节点(文本+元素) --> <xsl:apply-templates select="node()"/> </xsl:template> <xsl:template match="EMPH"> <xsl:choose> <xsl:when test="@BOLD=1"> <b> <!-- 递归处理子节点,支持嵌套EMPH结构 --> <xsl:apply-templates select="node()"/> </b> </xsl:when> <xsl:when test="@HL='HIGH'"> <sup> <xsl:apply-templates select="node()"/> </sup> </xsl:when> <xsl:when test="@HL='LOW'"> <!-- 按期望输出保留原始文本,无特殊标记 --> <xsl:apply-templates select="node()"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="node()"/> </xsl:otherwise> </xsl:choose> </xsl:template>
修复说明
- 按原始顺序处理节点:在
PARA模板里,用<xsl:apply-templates select="node()"/>替代原来的“先取文本再处理EMPH”逻辑,XSLT会严格遵循XML里的节点顺序(文本→EMPH→文本→EMPH)依次处理,保证输出顺序和原始结构一致。 - 递归处理嵌套节点:把每个
EMPH分支里的<xsl:value-of select="."/>替换为<xsl:apply-templates select="node()"/>,这样遇到嵌套的EMPH节点时,会自动调用对应模板处理子节点,而不是直接提取文本。比如STYLE="min_max"的EMPH会被正常遍历,它的子EMPH会分别应用LOW和HIGH的样式规则。 - 补充LOW样式分支:根据你的期望输出,
HL="LOW"的EMPH不需要特殊标记,新增这个分支保证逻辑覆盖完整。
修复后就能得到你想要的输出:1050 -50 +50 min<sup>-1</sup>。
内容的提问来源于stack exchange,提问作者KevinM
相关产品推荐
相关产品推荐

