如何检测元素

时间:2015-12-02 09:06:37

标签: xml xslt xpath

您好我有以下问题:

我需要检测某个元素是否包含子文本节点,但不包括前导和尾随空格,回车符,制表符和换行符。任何"空"空间不计入文本。

我发现这个函数 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元素,它也有文本节点?

1 个答案:

答案 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>