如何在xslt中修剪?

时间:2010-12-10 13:57:51

标签: xslt fxsl

我想左右修剪空白 in:
<xsl:value-of select="Datas/Data[@key='Name']/string"/>

我该怎么做?

5 个答案:

答案 0 :(得分:13)

normalize-space(Datas/Data[@key='Name']/string)可能就足够了,它会修剪空白区域以及开始和结束。然而它也会将任何空白区域折叠到一个空间,我不知道你是否想要它。

答案 1 :(得分:4)

最简单的方法是使用FXSL trim模板功能。

此转化

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="trim.xsl"/>
<xsl:output method="text"/>

  <xsl:template match="/">
    '<xsl:call-template name="trim">
        <xsl:with-param name="pStr" select="string(/*)"/>
    </xsl:call-template>'
  </xsl:template>
</xsl:stylesheet>

应用于此XML文档时

<someText>

   This is    some text   

</someText>

生成想要的正确结果

'This is    some text'

trim如何运作

很容易消除字符串中的所有起始空白字符,但困难的部分是消除所有结束的空白字符。

FXSL的trim函数/模板通过使用FXSL的另一个模板/函数来反转字符串来实现这一点。

所以,处理就像这样

  1. 消除领先的空白区域。

  2. 反转结果。

  3. 消除领先的空白。

  4. 最后反转。

  5. 可以看到FXSL 2.0中的trim()的完整代码(适用于XSLT 2.0) here。它几乎与FXSL 1.0的trim模板的代码(对于XSLT 1.0)相同。

答案 2 :(得分:4)

提供我在XSLT 2.0中使用的另一个解决方案,因为它更简洁和准确(normalize-space不是修剪)。

使用replace函数和正则表达式来获取内部内容减去前面和后面的空格。

replace(Datas/Data[@key='Name']/string,'^\s*(.+?)\s*$', '$1')

答案 3 :(得分:0)

将针对XSLT2用户的@ ricosrealm解决方案与针对XSLT1的@Dimitre进行比较(并检查FXSL-trim的行数)。 正则表达式替换函数非常简单,花费更少的CPU时间和更少的程序员时间。

对于2013年的XSLT1用户

如果您是XSLT1用户,可能是因为您没有选择使用XSLT2。示例:PHP依赖于LibXML2实现,它停留在1999标准中,没有实现2007年的标准。今天(2013年),只有一小部分XSLT1用户通过性能考虑来实现这一目标。

所以,如果你认为你被XSLT1和你的框架困住了,是时候知道并使用“注册函数”like on PHP(但是任何其他像Python或Javascript使用LibXML2可以使用LibXML2's extensions),以接近XSLT2自由/功能 请参阅您的语言的XSLTProcessor :: registerPHPFunctions。

PHP示例:

  <xsl:value-of 
       select="php:functionString( 'trim', Datas/Data[@key='Name']/string )"
  />

注意(编辑):对于非libXML2实现,如Microsoft(.NET)框架,如@ChristopheDebove所示(下面的评论),还有注册函数的解决方案。当然,对于Java来说,SAXON是当今唯一的XSLT2开源。

...如果有一天(请参阅关于何时herehere的意见)在同一框架(例如PHP)中用XSLT2替换XSLT1,则无需更改XSLT脚本, 因为预期注册的功能将是相同的。

答案 4 :(得分:0)

您只能使用XSLT 1.0自己制作:

如果只需要trim,则可以像下面的模板一样自己实现。它以递归方式调用自身并剥离字符,直到内置XSLT函数normalize-space()的第一个和最后一个字符与其余字符串的第一个和最后一个字符匹配为止。这两种情况基本上是左修剪和右修剪,首先进行左修剪(外部otherwise情况)。

在大型数据集上可能会比较慢,但效果很好:

<xsl:template name="Trim">
<xsl:param name="value"/>
<xsl:choose>
  <xsl:when test="string-length($value)=0 or string-length(normalize-space($value))=0">
    <xsl:value-of select="$value"/>
  </xsl:when>
  <xsl:when test="starts-with($value,substring(normalize-space($value),1,1))">
  <xsl:choose>
    <xsl:when test="starts-with(substring($value,string-length($value)-1,1),substring(normalize-space($value),string-length(normalize-space($value))-1,1))">
    <xsl:value-of select="$value"/>
    </xsl:when>
    <xsl:otherwise>
    <xsl:call-template name="Trim">
    <xsl:with-param name="value" select="substring($value,1,string-length($value)-1)"/>
    </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
  </xsl:when>
  <xsl:otherwise>
  <xsl:call-template name="Trim">
    <xsl:with-param name="value" select="substring($value,2)"/>
  </xsl:call-template>
  </xsl:otherwise>
</xsl:choose>
</xsl:template>

用法:

<xsl:call-template name="Trim"><xsl:with-param name="value" select="mynodehere"/></xsl:call-template>