2016-06-21 68 views
1

所以我的问题是这样的。我有一个在许多地方使用的变换文档,通常处理很多小格式变换。在一个特定情况下,我需要从结果中删除空格。输出看起来是这样的:XSLT:删除多余的空白字符保留节点

“\ n                   <我>的东西</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'的使用不像我预期的那样工作,它按字符工作。我使用了一种替换子字符串的转换。

+0

请给XML输入的reprsentative例子。 –

+0

\ n 东西喜欢带脚注的标题脚注这是脚注,其他转换大部分都会被删除。我们已经完成\ n Snow

+0

我应该补充说,这个例子是我正在使用的标题xml的一个例子,但是转换也能够接收各种大段的文本,包含多个段落, – Snow

回答

0

我有两个选择:

如果\ 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> 
1

当您使用normalize-space时,只使用片段的文本值,因此子节点被剥离。你必须把normalize-space成子节点,以及模板(那些由你<xsl:apply-templates/>

+0

不幸的是,我不能把标准化空间放到其他模板中,因为它们也处理具有线返回的文本,并且适当地如此。 – Snow

+0

但是你会在你显示的代码中删除这些换行符......?否则,你必须做一个略微修改的身份转换,指定一个“mode =”removewhite“(例如),并在里面做'text()'的标准化空间(搜索标识转换xslt,如果你有困难回来;-) –

+0

标记这是答案,因为解决方案来自对它的评论。 – Snow

0

它cound只是在输出缩进应用于你有< XSL:输出缩进=“是”/>在你的顶部xsl?或者,也许处理器正在执行缩进。使用< xsl:output indent =“no”/>应该吸收所有的\ n和缩进。

+0

换行符和额外间距直接来自输入数据。这是一个数据问题,其中一些Marklogic数据库条目在标签内存在应该不存在的换行符。 – Snow