创建用于添加序列的递归字符串函数

时间:2013-04-18 13:09:28

标签: xslt xslt-2.0

我遇到了一个具有挑战性的问题,到目前为止我无法解决。

在我的xlst中,我有一个包含字符串的变量。 我需要将以下序列[eol]添加到此字符串中。 在固定位置,即每65个字符

我想用一个函数或模板来递归添加这个charackter。 原因是字符串长度的长度可能会变化。

    <xsl:function name="funct:insert-eol" as="xs:string" >
    <xsl:param name="originalString" as="xs:string?"/>
    <xsl:variable name="length">
        <xsl:value-of select="string-length($originalString)"/>
    </xsl:variable>
    <xsl:variable name="start" as="xs:integer">
        <xsl:value-of select="1"/>
    </xsl:variable>
    <xsl:variable name="eol" as="xs:integer">
        <xsl:value-of select="65"/>
    </xsl:variable>
    <xsl:variable name="newLines">
        <xsl:value-of select="$length idiv number('65')"/>
    </xsl:variable>
    <xsl:for-each select="1 to $newLines">
        <xsl:value-of select="substring($originalString, $start, $eol)" />
    </xsl:for-each>
    </xsl:function>

我编写的代码越多,我需要引入的变量就越多。这仍然是我缺乏理解。

例如,我们希望每5个字符为[eol]

aaaaaaabbbbbbccccccccc

AAAAA [EOL] aabbb [EOL] bbbcc [EOL] CCCCC [EOL] CC


希望有人有我的起点..

关心Dirk

3 个答案:

答案 0 :(得分:2)

相当简单和简短 - 不需要递归(甚至可以指定为单个XPath表达式):

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:param name="pLLength" select="5"/>

 <xsl:template match="/*">
  <xsl:variable name="vText" select="string()"/>

  <xsl:for-each select="1 to string-length($vText) idiv $pLLength +1">
    <xsl:value-of select="substring($vText, $pLLength*(position()-1)+1, $pLLength)"/>
    <xsl:if test=
    "not(position() eq last()
       or position() eq last() and string-length($vText) mod $pLLength)">[eol]</xsl:if>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

对此XML文档应用此转换时:

<t>aaaaaaabbbbbbccccccccc</t>

产生了想要的正确结果:

aaaaa[eol]aabbb[eol]bbbcc[eol]ccccc[eol]cc

处理此XML文档时:

<t>aaaaaaabbbbbbcccccccccddd</t>

再次生成想要的正确结果:

aaaaa[eol]aabbb[eol]bbbcc[eol]ccccc[eol]ccddd[eol]

答案 1 :(得分:1)

您可以使用for-each-group

将其视为分组问题
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf">

<xsl:function name="mf:insert-eol" as="xs:string">
  <xsl:param name="input" as="xs:string"/>
  <xsl:param name="chunk-size" as="xs:integer"/>
  <xsl:value-of>
  <xsl:for-each-group select="string-to-codepoints($input)" group-by="(position() - 1) idiv $chunk-size">
    <xsl:if test="position() gt 1"><xsl:sequence select="'eol'"/></xsl:if>
    <xsl:sequence select="codepoints-to-string(current-group())"/>
  </xsl:for-each-group>
  </xsl:value-of>
</xsl:function>

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

<xsl:template match="text">
  <xsl:copy>
    <xsl:sequence select="mf:insert-eol(., 5)"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

该样式表转换

<root>
  <text>aaaaaaabbbbbbccccccccc</text>
</root>

<root>
  <text>aaaaaeolaabbbeolbbbcceolccccceolcc</text>
</root>

答案 2 :(得分:0)

试试这个:

<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xsl:param name="TextToChange" select="'aaaaaaabbbbbbccccccccc'"/>
  <xsl:param name="RequiredLength" select="xs:integer(5)"/>

  <xsl:template match="/">
    <xsl:call-template name="AddText"/>
  </xsl:template>

  <xsl:template name="AddText">
    <xsl:param name="Text" select="$TextToChange"/>
    <xsl:param name="TextLength" select="string-length($TextToChange)"/>
    <xsl:param name="start" select="xs:integer(1)"/>
    <xsl:param name="end" select="$RequiredLength"/>
    <xsl:choose>
      <xsl:when test="$TextLength gt $RequiredLength">
        <xsl:value-of select="substring($Text,$start,$end)"/>
        <xsl:text>[eol]</xsl:text>
        <xsl:call-template name="AddText">
          <xsl:with-param name="Text" select="substring-after($Text, substring($Text,$start,$end))"/>
          <xsl:with-param name="TextLength"
            select="string-length(substring-after($Text, substring($Text,$start,$end)))"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$Text"/>
      </xsl:otherwise>
    </xsl:choose>

  </xsl:template>

</xsl:stylesheet>