使用XSLT样式表控制XML文本输出的问题咨询
XSLT转换常见问题解答
针对你遇到的三个问题,我来逐个解释并给出实用解决方案:
1. 为何会输出“Some title sect 1 begin..”等未选中的内容?
这是因为XSLT的默认模板规则在暗中起作用。XSLT内置了一套默认处理逻辑:当你没有为某个节点编写匹配模板时,默认模板会自动处理这些节点——对于元素节点,它会递归遍历所有子节点;对于文本节点,它会直接输出文本内容。
你的模板只明确处理了sect1/variablelist节点,而sect1下的title、para等其他节点,以及它们的文本子节点,都被默认模板“接管”并输出了。要阻止这些无关内容,你可以添加一个根节点匹配模板,只处理你需要的部分:
<!-- 匹配根节点,仅处理目标variablelist --> <xsl:template match="/"> <xsl:apply-templates select="sect1/variablelist"/> </xsl:template>
这样就能跳过所有未被指定的节点,只输出你关注的内容。
2. 为何会出现多余的缩进和空格?
这些多余空白来自XML文件中的空白文本节点——你编写XML时的换行、缩进空格,在XML解析时会被当作合法的文本节点保留。默认模板同样会输出这些空白节点,所以你会看到零散的空格和换行。
解决方法很直接,在XSLT的xsl:stylesheet标签下添加xsl:strip-space指令,一键移除所有元素中的空白节点:
<xsl:strip-space elements="*"/>
3. 如何在“term 1”和“term 2”之间添加换行?
你可以在xsl:for-each循环中,输出完term内容后添加换行符。推荐使用XML实体 表示换行(跨平台兼容):
<xsl:for-each select="varlistentry"> <xsl:value-of select="term"/> <!-- 添加换行符 --> <xsl:text> </xsl:text> </xsl:for-each>
如果不想在最后一个term末尾多一个换行,也可以用position()判断:
<xsl:for-each select="varlistentry"> <xsl:value-of select="term"/> <xsl:if test="position() != last()"> <xsl:text> </xsl:text> </xsl:if> </xsl:for-each>
最终优化后的test.xslt
把这些修改整合后,你的样式表会变成这样:
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <!-- 仅处理目标节点 --> <xsl:template match="/"> <xsl:apply-templates select="sect1/variablelist"/> </xsl:template> <xsl:template match="sect1/variablelist"> <xsl:for-each select="varlistentry"> <xsl:value-of select="term"/> <xsl:if test="position() != last()"> <xsl:text> </xsl:text> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>
执行xsltproc test.xslt test.xml后,就能得到你期望的输出:
term 1 term 2
内容的提问来源于stack exchange,提问作者kibudude
相关产品推荐
相关产品推荐

