2011-10-19 10 views
2

私はいくつかのことを試したがっていました。今私は100ブロックに文字列を分割しようとしました。だから私はこれまでのところどのようになったのですか:XSLT 1.0で文字列を100ブロックに分割する

<xsl:template name="split100check"> 
    <xsl:param name="input"></xsl:param> 
    <xsl:variable name="newInput" select="concat(normalize-space($input), ' ')"></xsl:variable> 
    <xsl:variable name="start" select="substring($input, 1, 100)"></xsl:variable> 
    <xsl:variable name="end" select="substring($input, 101)"></xsl:variable> 
    <PART> 
     <xsl:value-of select="$start"></xsl:value-of> 
    </PART> 
    <xsl:if test="$end"> 
     <xsl:call-template name="split100check"> 
      <xsl:with-param name="input" select="$end"></xsl:with-param> 
     </xsl:call-template> 
    </xsl:if>9 
</xsl:template> 

これは私が達成したいものです。文字列を100ブロックにしますが、単語も分割します。例:

<main> 
    <long> 
    A very long text here [....] only for test 
    </long> 
</main> 

最初の100ブロックは "only"という単語で終了し、途中で終了するとします。最初のブロックは「非常に長いテキスト[....]」で、2番目のブロックは「テスト用」です。だから私は私が望むことをするためにそのテンプレートを構築する必要がありますか?

情報:

テキスト:10個のブロックを分割してそれがより明確な例を作成するには :私はXSLT 1.0

編集]を使用することができます「こんにちは私の友人」 - > 10blocksに分割は次のようになり

最初のブロック:<PART>Hello my f</PART>

第二のブロック:<PART>riend</PART>

私のアプローチと

私は言葉はこのようsplitedないことにしたい。

最初のブロック:<PART>Hello my </PART>

第二のブロック:<PARTR>friend </PART>

を第一のブロックOFCは、今はもうちょうど10文字長くはありませんが、それは問題ではありません。それは10文字ブロックに収まるように多くの言葉を入れなければならない。

gzでALEKS

+0

あなたは本当にあなたがほしいと言っていませんでした。専門用語で、あなたのための「言葉」とは何ですか?あなたは分割が単語で起こるときにどこで発生するようにしたいですか? - 単語を「スペースで区切られたもの」と定義した場合、単語の前に分割を入れてください*と*は、単語の分布が100文字以上の単語が存在しない(URLなどと思う)ことが合理的に確信していれば、 [私が別の質問のために作成した 'substring-before-last'テンプレートの](http://stackoverflow.com/questions/1119449/removing-the-last-characters-in-an-xslt-string/1119666 #1119666)。 – Tomalak

+0

ああ、十分に明快ではないことを申し訳ありません。言葉は私のための言葉です:)。私は上記のようにタグの間に非常に長いテキストがあるとしましょう。 [...]は長いテキストを象徴するはずです(何かを記述するような長いテキストを想像してください)。 理由を説明するだけです:10文字に分割し、「Hello my friend」という文字列を「Hello my f」と「friend」に分割するとしましょう。しかし、私は持っている: "こんにちは私"と "友人"。したがって、最後の単語がこの場合は10ブロックに収まらない場合は、それを認識して次のブロックに入れます。 – Aleks

+0

10文字の単語境界がない場合はどうなりますか?それは強制的に壊れるはずですね。唯一の単語境界が文字2の場合はどうでしょうか?それは早く壊れて、厄介な短い線を残すべきですか? (また、 'substring-before-last()'テンプレートに試しましたか?) – Tomalak

答えて

1

あなたはFXSLからSTR-スプリットツーラインテンプレートを使用することができます。

<text> 
Dec. 13 — As always for a presidential inaugural, security and surveillance were 
extremely tight in Washington, DC, last January. But as George W. Bush prepared to 
take the oath of office, security planners installed an extra layer of protection: a 
prototype software system to detect a biological attack. The U.S. Department of 
Defense, together with regional health and emergency-planning agencies, distributed 
a special patient-query sheet to military clinics, civilian hospitals and even aid 
stations along the parade route and at the inaugural balls. Software quickly 
analyzed complaints of seven key symptoms — from rashes to sore throats — for 
patterns that might indicate the early stages of a bio-attack. There was a brief 
scare: the system noticed a surge in flulike symptoms at military clinics. 
Thankfully, tests confirmed it was just that — the flu. 
</text> 

ように近いが超えない長さを有する所望の正当化(ライン:この変換は、以下のXML文書に適用される場合

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:f="http://fxsl.sf.net/" 
xmlns:ext="http://exslt.org/common" 
xmlns:str-split2lines-func="f:str-split2lines-func" 
exclude-result-prefixes="xsl f ext str-split2lines-func" 
> 


    <xsl:import href="dvc-str-foldl.xsl"/> 

    <!-- to be applied on text.xml --> 

    <str-split2lines-func:str-split2lines-func/> 

    <xsl:output indent="yes" omit-xml-declaration="yes"/> 

    <xsl:template match="/"> 
     <xsl:call-template name="str-split-to-lines"> 
     <xsl:with-param name="pStr" select="/*"/> 
     <xsl:with-param name="pLineLength" select="60"/> 
     <xsl:with-param name="pDelimiters" select="' &#9;&#10;&#13;'"/> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="str-split-to-lines"> 
     <xsl:param name="pStr"/> 
     <xsl:param name="pLineLength" select="60"/> 
     <xsl:param name="pDelimiters" select="' &#9;&#10;&#13;'"/> 

     <xsl:variable name="vsplit2linesFun" 
        select="document('')/*/str-split2lines-func:*[1]"/> 

     <xsl:variable name="vrtfParams"> 
     <delimiters><xsl:value-of select="$pDelimiters"/></delimiters> 
     <lineLength><xsl:copy-of select="$pLineLength"/></lineLength> 
     </xsl:variable> 

     <xsl:variable name="vResult"> 
      <xsl:call-template name="dvc-str-foldl"> 
      <xsl:with-param name="pFunc" select="$vsplit2linesFun"/> 
      <xsl:with-param name="pStr" select="$pStr"/> 
      <xsl:with-param name="pA0" select="ext:node-set($vrtfParams)"/> 
      </xsl:call-template> 
     </xsl:variable> 
     <xsl:for-each select="ext:node-set($vResult)/line"> 
     <xsl:for-each select="word"> 
      <xsl:value-of select="concat(., ' ')"/> 
     </xsl:for-each> 
     <xsl:value-of select="'&#xA;'"/> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="str-split2lines-func:*" mode="f:FXSL"> 
     <xsl:param name="arg1" select="/.."/> 
     <xsl:param name="arg2"/> 

     <xsl:copy-of select="$arg1/*[position() &lt; 3]"/> 
     <xsl:copy-of select="$arg1/line[position() != last()]"/> 

     <xsl:choose> 
     <xsl:when test="contains($arg1/*[1], $arg2)"> 
      <xsl:if test="string($arg1/word) or string($arg1/line/word)"> 
      <xsl:call-template name="fillLine"> 
       <xsl:with-param name="pLine" select="$arg1/line[last()]"/> 
       <xsl:with-param name="pWord" select="$arg1/word"/> 
       <xsl:with-param name="pLineLength" select="$arg1/*[2]"/> 
      </xsl:call-template> 
      </xsl:if> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy-of select="$arg1/line[last()]"/> 
      <word><xsl:value-of select="concat($arg1/word, $arg2)"/></word> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

     <!-- Test if the new word fits into the last line --> 
    <xsl:template name="fillLine"> 
     <xsl:param name="pLine" select="/.."/> 
     <xsl:param name="pWord" select="/.."/> 
     <xsl:param name="pLineLength" /> 

     <xsl:variable name="vnWordsInLine" select="count($pLine/word)"/> 
     <xsl:variable name="vLineLength" 
     select="string-length($pLine) + $vnWordsInLine"/> 
     <xsl:choose> 
     <xsl:when test="not($vLineLength + string-length($pWord) 
          > 
          $pLineLength)"> 
      <line> 
      <xsl:copy-of select="$pLine/*"/> 
      <xsl:copy-of select="$pWord"/> 
      </line> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy-of select="$pLine"/> 
      <line> 
      <xsl:copy-of select="$pWord"/> 
      </line> 
      <word/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

:ここ

は一例で60)が生成される:

Dec. 13 — As always for a presidential inaugural, security 
and surveillance were extremely tight in Washington, DC, 
last January. But as George W. Bush prepared to take the 
oath of office, security planners installed an extra layer 
of protection: a prototype software system to detect a 
biological attack. The U.S. Department of Defense, together 
with regional health and emergency-planning agencies, 
distributed a special patient-query sheet to military 
clinics, civilian hospitals and even aid stations along the 
parade route and at the inaugural balls. Software quickly 
analyzed complaints of seven key symptoms — from rashes to 
sore throats — for patterns that might indicate the early 
stages of a bio-attack. There was a brief scare: the system 
noticed a surge in flulike symptoms at military clinics. 
Thankfully, tests confirmed it was just that — the flu.