3

次のタスク
があります。長い文字列を含む xml 要素があります。<input>この要素を多数の htmlタグに変換するには、xsl を使用する必要があります。これは次のように機能します: 文字列が<input>フィールドがスクロールせずに保持できる長さよりも長い場合、同じテンプレートを再帰的に呼び出して、残りのテキストで別の入力フィールドを作成します。

問題は、文字列が単語の途中で分割されることがよくあることです。これは適切ではありません。

したがって、タグに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 &lt; 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>
4

3 に答える 3

6

次の再帰テンプレートを使用して、特定の区切り文字の最後のインデックスを返すことができます。

<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>
于 2012-09-29T02:11:10.673 に答える
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
于 2012-09-29T05:19:22.167 に答える
1

EXSLTsplitテンプレート ( description ; implementation ) を使用するかtokenize、文字列をスペースで分割することができます。次に、最後のテキスト ノードを除くすべてのテキスト ノードを出力したり、最後のテキスト ノードの長さを使用して最後のスペースのインデックスを取得したりできます。

ニーズに合わせて調整できるこのテンプレートも参照してください。

于 2012-09-28T15:05:17.527 に答える