2011-02-04 3 views
3

XSLTの個々の単語の周りにスパンタグ(または任意のタグ)をラップするにはどうすればよいですか?私はXSLT1を使用していますが、試してみるたびにスタックしているようです。XSLTを使用してタグの単語を囲む

基本的に、私は段落(またはテキストの文字列)に渡したい:

<p>This is my text!</p> 

と各単語の間に空白や句読点を維持し、そのように各単語をラップ:

<p><span class="word-1">This</span> <span class="word-2">is</span> <span class="word-3">my</span> <span class="word-4">text!</span> 

主にプレゼンテーション目的のために、私は助けていただければ幸いです

+0

句読点はpreviusに属していますか? –

答えて

4

このスタイルシート:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:param name="pSeparators">&#xA;&#x9;&#x20;,.;:?!()'"</xsl:param> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="p/text()" name="tokenize"> 
     <xsl:param name="pString" select="."/> 
     <xsl:param name="pMask" 
        select="translate(.,translate(.,$pSeparators,''),'')"/> 
     <xsl:param name="pCount" select="1"/> 
     <xsl:choose> 
      <xsl:when test="not($pString)"/> 
      <xsl:when test="$pMask"> 
       <xsl:variable name="vSeparator" 
           select="substring($pMask,1,1)"/> 
       <xsl:variable name="vString" 
           select="substring-before($pString,$vSeparator)"/> 
       <xsl:call-template name="tokenize"> 
        <xsl:with-param name="pString" select="$vString"/> 
        <xsl:with-param name="pMask"/> 
        <xsl:with-param name="pCount" select="$pCount"/> 
       </xsl:call-template> 
       <xsl:value-of select="$vSeparator"/> 
       <xsl:call-template name="tokenize"> 
        <xsl:with-param name="pString" 
           select="substring-after($pString,$vSeparator)"/> 
        <xsl:with-param name="pMask" 
            select="substring($pMask,2)"/> 
        <xsl:with-param name="pCount" 
            select="$pCount + boolean($vString)"/> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:otherwise> 
       <span class="word-{$pCount}"> 
        <xsl:value-of select="$pString"/> 
       </span> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

出力:

<p><span class="word-1">This</span> <span class="word-2">is</span> <span class="word-3">my</span> <span class="word-4">text</span>!</p> 

:トークン化、いくつかの区切りによります。 を編集:より良い名前。セパレータシーケンスに空白文字を追加する。

+0

+1。ニースと完全なソリューション。 – Flack

2

単純な再帰的な名前付きテンプレートは、トリックを行う必要があります:

<xsl:template name="wordsInTags"> 
     <xsl:param name="text" 
       select="."/> 
     <xsl:param name="index" 
       select="1"/> 
     <xsl:choose> 
     <xsl:when test="contains($text, ' ')"> 
      <span class="word-{$index}"> 
      <xsl:value-of select="substring-before($text, ' ')"/> 
      </span> 
      <xsl:text> </xsl:text> 
      <xsl:call-template name="wordsInTags"> 
      <xsl:with-param name="text"> 
       <xsl:value-of select="substring-after($text, ' ')"/> 
      </xsl:with-param> 
      <xsl:with-param name="index"> 
       <xsl:value-of select="$index + 1"/> 
      </xsl:with-param> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <span class="word-{$index}"> 
      <xsl:value-of select="$text"/> 
      </span> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

そして単に言葉がラップする必要があるの要素のためにそれを呼び出す:一緒に実際に素早くこの投げ

<xsl:template match="p"> 
     <p> 
     <xsl:call-template name="wordsInTags"/> 
     </p> 
    </xsl:template> 

を、それはいくつかのより多くの作業が必要になる場合がありますが、これはあなたが始める必要があります。