Xml XSLT-在循环中的每N个字符上拆分字符串

Xml XSLT-在循环中的每N个字符上拆分字符串,xml,xslt,Xml,Xslt,在我们的一个需求中,我们收到一个n字符的字符串,并在提供商处将其发送给SAP。由于目标端的一些限制,我们需要检查字符串,如果它超过100个字符,我们需要将其拆分并以两个不同的段(相同的名称)发送到目标应用程序,如 输入-这是一条测试消息……(直到150个字符) 在XSLT转换中,我们需要像 <text>first 100 char<text> <text> 101 to 200 char<text> ... 前100个字符 101至200个字符

在我们的一个需求中,我们收到一个n字符的字符串,并在提供商处将其发送给SAP。由于目标端的一些限制,我们需要检查字符串,如果它超过100个字符,我们需要将其拆分并以两个不同的段(相同的名称)发送到目标应用程序,如

输入-这是一条测试消息……(直到150个字符)

在XSLT转换中,我们需要像

<text>first 100 char<text>
<text> 101 to 200 char<text>
...
前100个字符
101至200个字符
...
由于字符数不是预定义的,所以我不能在这里使用子字符串函数。这应该是循环的一部分


有人可以帮忙吗。

在XSLT 2.0中,您可以这样做:

示例简化为将输入拆分为每个(最多)6个字符的标记。

XML

<input>abcde1abcde2abcde3abcde4abcde5abcde6abcde7abcde8abc</input>
abcde1abcde2abcde3abcde4abcde5abcde6abcde7abcde8abc
XSLT2.0

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/">
     <output>
        <xsl:variable name="string" select="input" />
        <xsl:for-each select="0 to (string-length($string) - 1) idiv 6">
            <token>
                <xsl:value-of select="substring($string, . * 6 + 1, 6)" />
            </token>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/*">
    <output>
      <xsl:call-template name="tokenize">
        <xsl:with-param name="input" select="."/>
      </xsl:call-template>
    </output>
  </xsl:template>

  <xsl:template name="tokenize">
    <xsl:param name="input"/>
    <xsl:param name="length" select="6"/>
    <token><xsl:value-of select="substring($input,1,$length)"/></token>
    <xsl:if test="substring($input,$length+1)">
      <xsl:call-template name="tokenize">
        <xsl:with-param name="input" select="substring($input,$length+1)"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

结果

<output>
   <token>abcde1</token>
   <token>abcde2</token>
   <token>abcde3</token>
   <token>abcde4</token>
   <token>abcde5</token>
   <token>abcde6</token>
   <token>abcde7</token>
   <token>abcde8</token>
   <token>abc</token>
</output>
<output>
   <token>abcde1</token>
   <token>abcde2</token>
   <token>abcde3</token>
   <token>abcde4</token>
   <token>abcde5</token>
   <token>abcde6</token>
   <token>abcde7</token>
   <token>abcde8</token>
   <token>abc</token>
</output>

abcde1
abcde2
abcde3
abcde4
abcde5
abcde6
abcde7
abcde8
abc
这里有一个1.0的选项(也适用于2.0)。它使用递归模板调用

XML输入(谢谢Michael)

abcde1abcde2abcde3abcde4abcde5abcde6abcde7abcde8abc
XSLT1.0

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/">
     <output>
        <xsl:variable name="string" select="input" />
        <xsl:for-each select="0 to (string-length($string) - 1) idiv 6">
            <token>
                <xsl:value-of select="substring($string, . * 6 + 1, 6)" />
            </token>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/*">
    <output>
      <xsl:call-template name="tokenize">
        <xsl:with-param name="input" select="."/>
      </xsl:call-template>
    </output>
  </xsl:template>

  <xsl:template name="tokenize">
    <xsl:param name="input"/>
    <xsl:param name="length" select="6"/>
    <token><xsl:value-of select="substring($input,1,$length)"/></token>
    <xsl:if test="substring($input,$length+1)">
      <xsl:call-template name="tokenize">
        <xsl:with-param name="input" select="substring($input,$length+1)"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

XML输出

<output>
   <token>abcde1</token>
   <token>abcde2</token>
   <token>abcde3</token>
   <token>abcde4</token>
   <token>abcde5</token>
   <token>abcde6</token>
   <token>abcde7</token>
   <token>abcde8</token>
   <token>abc</token>
</output>
<output>
   <token>abcde1</token>
   <token>abcde2</token>
   <token>abcde3</token>
   <token>abcde4</token>
   <token>abcde5</token>
   <token>abcde6</token>
   <token>abcde7</token>
   <token>abcde8</token>
   <token>abc</token>
</output>

abcde1
abcde2
abcde3
abcde4
abcde5
abcde6
abcde7
abcde8
abc

您能使用XSLT 2.0吗?我不这么认为。。因为我必须改变现有的XSL,它的意思是。。。所以我想我们现在使用的是1.0版本,它是XML版本,而不是XSLT版本。@kumarb不,这并不意味着什么。真正的问题是您正在使用(或将在实际生产中使用)哪个处理器。如果您不知道,请看如何在这里找到答案:是的,我的XSLT支持2.0。刚刚检查过。谢谢,我知道XSLT2.0对我有用。不过,我试图了解是什么特定函数导致了在XSLT 1.0版上运行它的问题。我们在这里使用相同的字符串函数。如果可能,请建议使用1.0版本。当我试图通过更改为2.0版来部署现有代码时,希望现有函数不应该这样做break@kumarb这不能在XSLT 1.0中运行,因为它没有XPath 2.0中引入的
to
idiv
运算符要在XSLT1.0中实现这一点,需要做更多的工作,我将不这样做。