我有以下任务:
有一个包含长字符串的xml元素。我需要使用xsl将此元素转换为许多html <input>
标记。它的工作原理如下:如果字符串长于<input>
字段可以保持而不滚动我递归调用相同的模板以创建另一个带有remainingig文本的输入字段。
问题是字符串经常在单词的中间分开,这是不好的。
所以我需要找到最后space
个字符的位置,该位置不大于适合<input>
标记的子字符串的大小,并且只打印行前的子字符串。
所以我准备了一个最大长度的子字符串,它可以放在字段中,但我不知道如何获取其中最后一个space
的索引并将其作为参数传递给下一个调用功能。
UPD:这是我到目前为止所拥有的
<xsl:template name="multilineInput">
<xsl:param name="input" select="."/>
<xsl:param name="maxFirst" select="."/>
<xsl:param name="firstLineWidth" select="."/>
<input>
<xsl:attribute name="readonly">readonly</xsl:attribute>
<xsl:attribute name="class">input_multiline</xsl:attribute>
<xsl:attribute name="style">width = "<xsl:value-of select="$firstLineWidth"/>"</xsl:attribute>
<xsl:attribute name="type">text</xsl:attribute>
<xsl:attribute name="value"><xsl:value-of select="substring($input, 1, $maxFirst)"/></xsl:attribute>
</input>
<xsl:if test="$maxFirst < string-length($input)">
<xsl:call-template name="multilineInput">
<xsl:with-param name="input" select="substring($input, $maxFirst+1, string-length($input)-$maxFirst)"/>
<xsl:with-param name="maxFirst" select="110"/>
<xsl:with-param name="firstLineWidth" select="'980'"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
答案 0 :(得分:6)
以下递归模板可用于返回给定分隔符的last-index:
<xsl:template name="last-index-of">
<xsl:param name="txt"/>
<xsl:param name="remainder" select="$txt"/>
<xsl:param name="delimiter" select="' '"/>
<xsl:choose>
<xsl:when test="contains($remainder, $delimiter)">
<xsl:call-template name="last-index-of">
<xsl:with-param name="txt" select="$txt"/>
<xsl:with-param name="remainder" select="substring-after($remainder, $delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="lastIndex" select="string-length(substring($txt, 1, string-length($txt)-string-length($remainder)))+1"/>
<xsl:choose>
<xsl:when test="string-length($remainder)=0">
<xsl:value-of select="string-length($txt)"/>
</xsl:when>
<xsl:when test="$lastIndex>0">
<xsl:value-of select="($lastIndex - string-length($delimiter))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
可以像这样调用:
<xsl:call-template name="last-index-of">
<xsl:with-param name="txt" select="'The quick brown fox jumped over the lazy dog.'"/>
<xsl:with-param name="delimiter" select="' '"></xsl:with-param>
</xsl:call-template>
并返回:41
您可以将模板调用的结果分配给如下变量:
<xsl:variable name="last-index">
<xsl:call-template name="last-index-of">
<xsl:with-param name="txt" select="'The quick brown fox jumped over the lazy dog.'"/>
<xsl:with-param name="delimiter" select="' '"></xsl:with-param>
</xsl:call-template>
</xsl:variable>
答案 1 :(得分:4)
此转换实现了一种简单而有效的算法:字符串中的最后一个空格是反向字符串中的第一个空格:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:call-template name="lastCharIndex">
<xsl:with-param name="pText" select=
"'The quick brown fox jumped over the lazy dog.'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="lastCharIndex">
<xsl:param name="pText"/>
<xsl:param name="pChar" select="' '"/>
<xsl:variable name="vRev">
<xsl:call-template name="reverse">
<xsl:with-param name="pStr" select="$pText"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select=
"string-length($pText) - string-length(substring-before($vRev, $pChar))"/>
</xsl:template>
<xsl:template name="reverse">
<xsl:param name="pStr"/>
<xsl:variable name="vLength" select="string-length($pStr)"/>
<xsl:choose>
<xsl:when test="$vLength = 1"><xsl:value-of select="$pStr"/></xsl:when>
<xsl:otherwise>
<xsl:variable name="vHalfLength" select="floor($vLength div 2)"/>
<xsl:variable name="vrevHalf1">
<xsl:call-template name="reverse">
<xsl:with-param name="pStr"
select="substring($pStr, 1, $vHalfLength)"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="vrevHalf2">
<xsl:call-template name="reverse">
<xsl:with-param name="pStr"
select="substring($pStr, $vHalfLength+1)"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat($vrevHalf2, $vrevHalf1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
当对任何XML文档(未使用)应用此转换时,会生成所需的正确结果:
41
答案 2 :(得分:1)
您可以使用EXSLT split
模板(description; implementation)或tokenize
将字符串拆分为空格。然后你可以打印除最后一个之外的所有文本节点,和/或使用最后一个文本节点的长度来获得最后一个空格的索引。
另见this template您可以根据自己的需要调整。