我有一个分隔的字符串,如下所示
FirstName&LastName&Address1&Address2&City&State&country&
我需要根据分隔符的出现次数来分割字符串。
说,如果我需要字符串中的前四个值,我应该得到输出 两个不同的变量,其中第一个变量应该有字符串 前四个值和第二个变量具有剩余的字符串。
我不想使用exslt或任何其他扩展名。 请帮我一个简单的解决方案。
Input:
<xsl:variable name="index" select='4' />
<xsl:variable name="delimitedString" select='FirstName&LastName&Address1&Address2&City&State&country&' />
Output:
<xsl:variable name="requiredString">
FirstName&LastName&Address1&Address2&
</xsl:variable>
<xsl:variable name="remainingString">
City&State&country&
</xsl:variable>
答案 0 :(得分:2)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pSplitIndex" select="4"/>
<xsl:template match="text()" name="splitAt">
<xsl:param name="pLeft" select="''"/>
<xsl:param name="pRight" select="."/>
<xsl:param name="pSplitAt" select="$pSplitIndex"/>
<xsl:param name="pDelim" select="'&'"/>
<xsl:choose>
<xsl:when test=
"not(string-length($pRight))
or
not(contains($pRight, $pDelim))
">
<t1>
<xsl:value-of select="concat($pLeft, $pRight)"/>
</t1>
<t2/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$pSplitAt = 0">
<t1><xsl:value-of select="$pLeft"/></t1>
<t2><xsl:value-of select="$pRight"/></t2>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="splitAt">
<xsl:with-param name="pLeft" select=
"concat($pLeft, substring-before($pRight, $pDelim), $pDelim)
"/>
<xsl:with-param name="pRight"
select="substring-after($pRight, $pDelim)"/>
<xsl:with-param name="pSplitAt" select="$pSplitAt -1"/>
<xsl:with-param name="pDelim" select="$pDelim"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
应用于此XML文档时:
<t>FirstName&LastName&Address1&Address2&City&State&country&</t>
生成所需的两个字符串,这些字符串是在第四个/t/text()
分隔符处拆分&
而产生的:
<t1>FirstName&LastName&Address1&Address2&</t1>
<t2>City&State&country&</t2>
您可以定义一个变量,例如vrtfSplitResult
,其主体是将模板应用于包含该字符串的文本节点的结果。然后,如果您可以使用xxx:node-set()
扩展名,则要定义的两个变量是:
<xsl:variable name="requiredString"
select="xxx:node-set($vrtfSplitResult)/*/t1">
<xsl:variable name="remainingString"
select="xxx:node-set($vrtfSplitResult)/*/t2">
如果您甚至不允许使用xxx:node-set()
扩展功能,那么您应该使用类似的命名模板:getStartingString
。这几乎是上面splitAt
模板的逻辑:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pSplitIndex" select="4"/>
<xsl:template match="text()">
<xsl:variable name="vrequiredString">
<xsl:call-template name="getStartingString"/>
</xsl:variable>
<xsl:variable name="vremainingString" select=
"substring-after(.,$vrequiredString)"/>
<t>
<t1><xsl:value-of select="$vrequiredString"/></t1>
<t2><xsl:value-of select="$vremainingString"/></t2>
</t>
</xsl:template>
<xsl:template name="getStartingString">
<xsl:param name="pLeft" select="''"/>
<xsl:param name="pRight" select="."/>
<xsl:param name="pSplitAt" select="$pSplitIndex"/>
<xsl:param name="pDelim" select="'&'"/>
<xsl:choose>
<xsl:when test=
"not(string-length($pRight))
or
not(contains($pRight, $pDelim))
">
<xsl:value-of select="$pLeft"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$pSplitAt = 0">
<xsl:value-of select="$pLeft"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="getStartingString">
<xsl:with-param name="pLeft" select=
"concat($pLeft, substring-before($pRight, $pDelim), $pDelim)
"/>
<xsl:with-param name="pRight"
select="substring-after($pRight, $pDelim)"/>
<xsl:with-param name="pSplitAt" select="$pSplitAt -1"/>
<xsl:with-param name="pDelim" select="$pDelim"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
将此转换应用于同一XML文档时,会再次生成所需的正确结果:
<t>
<t1>FirstName&LastName&Address1&Address2&</t1>
<t2>City&State&country&</t2>
</t>