XSLT:删除保留节点的多余空格字符

时间:2016-06-21 08:00:42

标签: xml xslt xslt-1.0

所以我的问题是这个。我有一个转换文档,在许多地方使用,并通常处理许多小格式转换。在一个特定的情况下,我需要从结果中删除空格。输出看起来像:

'\ n< I> Something< / I>非常重要的上标注< SUP> 1< / SUP> \ n'

我尝试过各种变体:

<xsl:template match="no_whitespace">
    <xsl:variable name="result">
        <xsl:apply-templates/>
    </xsl:variable>
    <xsl:copy-of select="normalize-space($result)"/>
</xsl:template>

但从输出中剥离子节点。我必须非常小心,不要设置像'text()'这样的通用模板,因为它会干扰转换的一般处理。好像我在这里遗漏了一些明显的东西。

编辑:尝试按照Stefan-Hegny的建议写一个身份变换。

<xsl:template match="title_full">
    <xsl:apply-templates mode="stripwhitespace"/>
</xsl:template>

<xsl:template match="text()" mode="stripwhitespace">
    <xsl:value-of select="normalize-space(translate(., '\n', ''))"/>
</xsl:template>

<xsl:template match="/ | @* | *" mode="stripwhitespace">
    <xsl:apply-templates select="."/>
</xsl:template>

这解决了我的问题,即删除标记最高级别的空格和换行符,然后允许转换正常进行。为这个模糊不清的问题道歉,并感谢您的帮助。

编辑第二个:使用'translate'不能像我预期的那样工作,它逐个字符地工作。我使用了一个替换子串的变换。

3 个答案:

答案 0 :(得分:2)

当您使用normalize-space时,仅使用片段的文本值,从而剥离子节点。您还必须将normalize-space放入子节点的模板中(由<xsl:apply-templates/>

应用的模板)

答案 1 :(得分:1)

它只是输出中的缩进。你有&lt; xsl:output indent =&#34; yes&#34; /&gt;在你的顶部xsl?或者处理器可能正在执行缩进。使用&lt; xsl:output indent =&#34; no&#34; /&gt;应该吸收所有的\ n和缩进。

答案 2 :(得分:1)

我有两个选择:

如果\ n它不是文字,那么这样做:

<xsl:template match="text()[ancestor-or-self::no_whitespace]">
    <xsl:value-of select="normalize-space(.)"/>
</xsl:template>

清理no_whitespace标记处及其下方的所有空白区域。

如果\ n是字符串中的文字,那么它就会变得更加复杂以摆脱\ n。使用此:

<xsl:template name="strip_newline">
    <xsl:param name="string"/>
    <xsl:value-of select="substring-before($string,'\n')"/>
    <xsl:variable name="rhs" select="substring-after($string,'\n')"/>
    <xsl:if test="$rhs">
        <xsl:call-template name="strip_newline">
            <xsl:with-param name="string" select="$rhs"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template match="text()[ancestor-or-self::no_whitespace]">
    <xsl:value-of select="normalize-space(.)"/>
</xsl:template>

<xsl:template match="text()[ancestor-or-self::no_whitespace][contains(.,'\n')]">
    <xsl:variable name="cleantext">
        <xsl:call-template name="strip_newline">
            <xsl:with-param name="string" select="."/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="normalize-space($cleantext)"/>
</xsl:template>

在这两种情况下,我假设您已经在xsl的其他位置安装了身份模板:

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>