1

xslを使用してn個のコメント要素のみを選択するにはどうすればよいですか。n個の文字を選択できますが、単語の途中でスナップして見苦しくなります。

'comments'ノードの単語の総数を数えることができましたが、合計20の単語がある場合、15の単語のように表示する方法がわかりません。

  <div class="NewsDescription">
  <xsl:value-of select="string-length(translate(normalize-space(@Comments),'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',''))+1" /> 
    <xsl:value-of select="substring(@Comments,0,120)"/>
    <xsl:if test="string-length(@Comments) &gt; 120">…&lt;/xsl:if>
    <a href="{$SafeLinkUrl}" class="ReadMore" style="font-size:11px ;font-family:Arial, Helvetica, sans-serif;color :#00aeef">Read More</a> 
   </div>

実際のxmlはこんな感じです。動的ページの右側に「関連ストーリー」の方法でストーリーピースをロールアップしようとしています。

<news>
   <title>Story title</title>
    <comments> story gist here..a couple of sentences.</comments>
    <content> actualy story </content>

助けてください。このリソースはMarcandersenによって見つけましたが、xslは複雑すぎて、フィルターをかけて自分自身を利用することはできません。

http://sympmarc.com/2010/07/13/displaying-the-first-n-words-of-announcement-bodies-with-xsl-in-a-dvwp/

XSLの達人からの助けをいただければ幸いです。

4

1 に答える 1

1

これは、非再帰的で純粋なXSLT1.0ソリューションです。

<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:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
 <xsl:variable name="vLower" select="'abcdefghijklmnopqrstuvwxyz'"/>
 <xsl:variable name="vDigits" select="'0123456789'"/>

 <xsl:variable name="vAlhanum" select="concat($vLower, $vUpper, $vDigits)"/>

 <xsl:template match="comments">
   <xsl:param name="pText" select="."/>
     <xsl:choose>
       <xsl:when test="not(string-length($pText) > 120)">
         <xsl:value-of select="$pText"/>
       </xsl:when>
         <xsl:otherwise>
           <xsl:variable name="vTruncated" select="substring($pText, 1, 121)"/>
             <xsl:variable name="vPunct" 
                           select="translate($vTruncated, $vAlhanum, '')"/>
           <xsl:for-each select=
           "(document('')//node() | document('')//@* | document('')//namespace::*)
                           [not(position() > 121)]">

             <xsl:variable name="vPos" select="122 - position()"/>
             <xsl:variable name="vRemaining" select="substring($vTruncated, $vPos+1)"/>

             <xsl:if test=
              "contains($vPunct, substring($vTruncated, $vPos, 1))
              and
               contains($vAlhanum, substring($vTruncated, $vPos -1, 1))
              and
                 string-length(translate($vRemaining, $vPunct, ''))
                         = string-length($vRemaining)
              ">
              <xsl:value-of select="substring($vTruncated, 1, $vPos -1)"/>
             </xsl:if>
           </xsl:for-each>
      </xsl:otherwise>
     </xsl:choose>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

この変換が次のXMLドキュメントに適用される場合:

<news>
   <title>Story title</title>
    <comments> story gist here..a couple of sentences. Many more sentences ...
even some more text with lots of meaning and sense aaand a lot of humor. </comments>
    <content> actualy story </content>
</news>

必要な正しい結果が生成されます:

 story gist here..a couple of sentences. Many more sentences ...
even some more text with lots of meaning and sense
于 2013-02-17T01:20:48.143 に答える