您好我有以下问题:
我需要检测某个元素是否包含子文本节点,但不包括前导和尾随空格,回车符,制表符和换行符。任何"空"空间不计入文本。
我发现这个函数 normalize-space(),它对我有用。但是如果文本节点放在嵌套元素之后,则函数无法找到它。例如:
<list>
<list-item/>
This is the text node
</list>
因此,当前上下文匹配时,<list>
元素<xsl:value-of select="noramalize-space(text())"/>
返回空字符串。但它应该返回&#34; 这是文本节点&#34;不是吗?
以下是我正在尝试的代码:
.XML :
<catalog>
<cd>
<empty-element>
<nested-empty-element/>
</empty-element>
<title>Empire Burlesque</title>
<list>
<list-itme>
<bullet>This is bullet</bullet>
</list-itme>
This is the text node
</list>
<artist>Bob Dylan</artist>
</cd>
</catalog>
的.xsl :
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="/catalog/cd"/>
</root>
</xsl:template>
<xsl:template match="cd">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
<xsl:if test="normalize-space(text())">
<para>
<xsl:value-of select="."/>
</para>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
转换后我得到了这个结果:
<root>
<para>Empire Burlesque</para>
<para>Bob Dylan</para>
</root>
问题是:为什么我没有得到这个结果?:
<root>
<para>Empire Burlesque</para>
<para>This is the text node</para>
<para>Bob Dylan</para>
</root>
为什么不处理list
元素,它也有文本节点?
答案 0 :(得分:2)
这是因为在list
之前list-itme
下面有一个空白文本节点(我添加了一个注释来显示其中的位置。从技术上讲,你会有两个空白节点用于下面的XML一个在评论之前,一个在之后)
<list> <!-- Whitespace text node here -->
<list-itme>
<bullet>This is bullet</bullet>
</list-itme>
This is the text node
</list>
如果要忽略这些空白节点,则可以使用xsl:strip-space
命令忽略它们
<xsl:strip-space elements="*" />
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:strip-space elements="*" />
<xsl:template match="/">
<root>
<xsl:apply-templates select="/catalog/cd"/>
</root>
</xsl:template>
<xsl:template match="cd">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
<xsl:if test="normalize-space(text())">
<para>
<xsl:value-of select="normalize-space(text())"/>
</para>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
或者,可以通过测试normalize-space不为空的任何文本节点(当前表达式规范化第一个文本节点)来实现相同的结果。
<xsl:if test="text()[normalize-space()]">
试试这个
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="/catalog/cd"/>
</root>
</xsl:template>
<xsl:template match="cd">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
<xsl:if test="text()[normalize-space()]">
<para>
<xsl:value-of select="normalize-space(text()[normalize-space()])"/>
</para>
</xsl:if>
</xsl:template>
</xsl:stylesheet>