为什么<xsl:for-each select="text()">
会忽略空格?
示例XML源:
<body>
Things<note>such as people</note> <note>or animals</note>act in crazy ways.
</body>
示例XSL:
<xsl:template match="body">
<output>
<xsl:for-each select="text()">
<text>
<xsl:value-of select="."/>
</text>
</xsl:for-each>
</output>
</xsl:template>
我希望这个输出:
<output>
<text>Things</text><text> </text><text>act in crazy ways.</text>
</output>
但我得到的是:
<output>
<text>Things</text><text>act in crazy ways.</text>
</output>
有人可以告诉我一些有用的方法吗?
谢谢!
答案 0 :(得分:3)
每个XSLT处理器(实际上来自XML树提供程序)都有关于输入源中仅空白文本节点的不同选择。
大部分(最重要的......)都尊重xsl:preserve-space
指令。
答案 1 :(得分:2)
并不是<xsl:for-each>
忽略空白文本节点,而是在样式表模板看到它们之前,解析输入文档时可能会剥离仅空白文本节点。
根据XSLT规范,默认情况下,XSLT会从样式表文档中删除仅空白文本节点,但<xsl:text>
元素除外;但除非您使用<xsl:strip-space>
,否则不会将其从源文档中删除。
XSLT 1.0 spec以这种方式描述:
在源文档树之后 或样式表文件已经 建造,但在它之前 否则由XSLT处理,一些文本 节点被剥离。文本节点是 从不剥离,除非它只包含 空白字符。剥离 text节点从中删除文本节点 那个树。剥离过程需要 作为输入的一组元素名称 哪个空白必须保留。 剥离过程适用于 样式表和源文档, 但是保留了空白的一组 元素名称已确定 不同的样式表和 来源文件。
如果有任何文本节点,则会保留该文本节点 以下申请:
文本节点的父节点的元素名称位于保留空白元素名称的集合中。
文本节点至少包含一个非空白字符。与XML一样,空格字符为#x20,#x9,#xD或#xA。
文本节点的祖先元素具有值为preserve的xml:space属性,并且没有更近的祖先元素具有值为default的xml:space。
否则,文本节点被剥离。
xml:space属性不是 从树上剥下来。
注意:这意味着如果在a上指定了xml:space属性 文字结果元素,它将是 包含在结果中。
对于样式表,一组 保留空格的元素名称 仅包含xsl:text。
对于源文档,请设置 保留空格的元素名称是 由xsl指定:strip-space和 xsl:preserve-space顶级元素。这些元素每个都有一个elements属性,其值是以空格分隔的NameTests列表。 最初,保留空白元素名称的集合包含所有元素名称。 [emphasis mine]如果元素名称与xsl:strip-space元素中的NameTest匹配,则将其从集合中删除保留空格的元素名称。如果元素名称与xsl:preserve-space元素中的NameTest匹配,则将其添加到保留空白元素名称的集合中。
总而言之,除非您在样式表中使用<xsl:strip-space>
顶级元素,否则不应该使用源文档进行剥离。如果您没有使用<xsl:strip-space>
,请告诉我们有关您的XSLT处理器和顶级样式表元素的更多信息。
根据this article,并非每个XSLT处理器都遵守规范中描述的默认行为。您可以尝试将以下内容添加为<xsl:stylesheet>
的子项,并查看它是否解决了问题:
<xsl:preserve-space elements="*"/>