XSLT 1.0如何遍历子节点并根据节点类型输出指定内容
XSLT 1.0 节点文本合并问题
输入XML
<doc> <article> <text> <p> paragraph 1 </p> <p> paragraph 2 </p> <inter> inter 1 </inter> <p> paragraph 3 </p> <p> paragraph 4 </p> <inter> inter 2 </inter> <p> paragraph 5 </p> </text> </article> </doc>
期望输出
<doc> <article> <text> [TEXT] paragraph 1 paragraph 2 [INTER] inter 1 paragraph 3 paragraph 4 [INTER] inter 2 paragraph 5 </text> </article> </doc>
尝试的XSLT代码(未生效)
<xsl:template match="/doc"> <doc> <article> <text> <xsl:text>[TEXT]
</xsl:text> <xsl:for-each select="article/text"> <xsl:choose> <xsl:when test="p"> <xsl:value-of select="p"/> <xsl:text>
</xsl:text> </xsl:when> <xsl:when test="intertitre"> <xsl:text>[INTER]
</xsl:text> <xsl:value-of select="intertitre"/> <xsl:text>
</xsl:text> </xsl:when> </xsl:choose> </xsl:for-each> </text> </article> </doc> </xsl:template>
当前错误输出
<doc> <article> <text> [TEXT] paragraph 1 </text> </article> </doc>
问题原因及解决方案
你的代码存在三个关键问题:
- 遍历对象错误:
for-each select="article/text"只遍历了<text>节点本身,而非它的子节点(<p>和<inter>),需改为遍历article/text/*。 - 节点名称不匹配:XML中的节点是
<inter>,但代码里写的是intertitre,导致无法匹配目标节点。 <p>节点取值错误:xsl:value-of select="p"只会取第一个<p>的文本,遍历子节点时需用.指代当前节点。
修正后的XSLT代码如下:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/doc"> <doc> <article> <text> <xsl:text>[TEXT]
</xsl:text> <!-- 遍历text下的所有子节点 --> <xsl:for-each select="article/text/*"> <xsl:choose> <!-- 匹配p节点,输出其文本 --> <xsl:when test="self::p"> <xsl:value-of select="normalize-space(.)"/> <xsl:text>
</xsl:text> </xsl:when> <!-- 匹配inter节点,先输出[INTER]再输出文本 --> <xsl:when test="self::inter"> <xsl:text>[INTER]
</xsl:text> <xsl:value-of select="normalize-space(.)"/> <xsl:text>
</xsl:text> </xsl:when> </xsl:choose> </xsl:for-each> </text> </article> </doc> </xsl:template> </xsl:stylesheet>
代码说明:
article/text/*:精准遍历<text>下的每一个子节点(<p>和<inter>)。self::p和self::inter:明确匹配当前节点类型,避免逻辑混淆。normalize-space(.):去除文本前后的空白和换行,让输出格式更整洁。
内容的提问来源于stack exchange,提问作者Seb Mainguet
相关产品推荐
相关产品推荐

