嗨,我有以下问题:
我需要检测某些元素中是否有子文本节点,但不包括前导和尾随空格,回车,制表符和换行符。任何“空白”空间都不会计入文字。
我发现此函数normalize-space()对我来说部分起作用。但是,如果将文本节点放置在嵌套元素之后,则函数将找不到它。例如:
<list>
<list-item/>
This is the text node
</list>
因此,当当前上下文匹配时,
<list>
元素<xsl:value-of select="noramalize-space(text())"/>
返回空字符串。但是它应该返回“ This is the text node”,不是吗?这是我正在尝试的代码:
.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
元素,它也具有文本节点?
最佳答案
这是因为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>
关于xml - 如何在元素中检测文本节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34038663/