2016-09-06 17 views
0

XSLT 2.0を使用して解決した問題がありますが、XSLT 1.0で同じことをする必要があります(XSLT 1.0互換プロセッサ)。実際にXSLT 1.0の段落のテキストと要素の折り返し

、私はXHTMLやXMLの異なる種類の、そしておそらく多少異なるシナリオを必要としているが、私はこれまでの一般的な解決策を見つけるために簡単にするためにXHTMLの例をあげる:

セイIこのようなHTMLテーブルがあります。

<table frame="void"> 
     <col width="50%" /> 
     <col width="50%" /> 
     <thead> 
      <tr> 
       <th></th> 
       <th></th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr> 
       <td>text text <b>text</b> text <i>text</i> text</td> 
       <td>text text <b>text</b> text <i>text</i> text<img src="mypic.png" alt="mypic" 
        />text <b>text</b> text</td> 
      </tr> 
      <tr> 
       <td> 
        <table frame="void"> 
         <col width="50%" /> 
         <col width="50%" /> 
         <thead> 
          <tr> 
           <th></th> 
           <th></th> 
          </tr> 
         </thead> 
         <tbody> 
          <tr> 
           <td></td> 
           <td></td> 
          </tr> 
          <tr> 
           <td></td> 
           <td></td> 
          </tr> 
         </tbody> 
        </table> 
       </td> 
       <td><img src="mypic.png" alt="mypic" /></td> 
      </tr> 
      <tr> 
       <td></td> 
       <td></td> 
      </tr> 
     </tbody> 
    </table> 

をそして私が今欲しいのは、これを取得するには、<p>タグと表のセル内のすべてのテキストとインライン要素をラップすることです:

<table frame="void"> 
     <col width="50%" /> 
     <col width="50%" /> 
     <thead> 
      <tr> 
       <th></th> 
       <th></th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr> 
       <td> 
        <p>text text <b>text</b> text <i>text</i> text</p> 
       </td> 
       <td><p>text text <b>text</b> text <i>text</i> text</p><img src="mypic.png" 
         alt="mypic" /><p>text <b>text</b> text</p></td> 
      </tr> 
      <tr> 
       <td> 
        <table frame="void"> 
         <col width="50%" /> 
         <col width="50%" /> 
         <thead> 
          <tr> 
           <th></th> 
           <th></th> 
          </tr> 
         </thead> 
         <tbody> 
          <tr> 
           <td></td> 
           <td></td> 
          </tr> 
          <tr> 
           <td></td> 
           <td></td> 
          </tr> 
         </tbody> 
        </table> 
       </td> 
       <td><img src="mypic.png" alt="mypic" /></td> 
      </tr> 
      <tr> 
       <td></td> 
       <td></td> 
      </tr> 
     </tbody> 
    </table> 

他のいくつかのセルにはイメージとネストしたテーブルがあります。それらのセルに画像や表だけがあり(テキストやインライン要素がない場合)、それらをpタグで囲むべきではありません。

イメージの1つには、周囲のテキストとインライン要素があります。そのような場合、イメージの前のテキストとインラインは、イメージ(またはテーブルまたはそれ以外の要素であってもよい)の前にpタグでラップする必要があり、イメージの後のテキスト/インラインは別のpタグでラップする必要があります。 (このユースケースでは、imgは非インライン要素btwとみなされます)。

だけではなく、子テンプレートを適用するテーブルセルのテンプレートからそれを呼び出して、私はこれを処理するために、このテンプレートを使用しているXSLT 2.0でこれを行う:

<xsl:template name="wrapInPara"> 
    <xsl:apply-templates select="@class"></xsl:apply-templates> 
    <xsl:for-each-group select="node()[not(self::text() and normalize-space(.) = '')]"    
     group-adjacent="boolean(self::text() | self::e:b | self::e:i | self::e:em | self::e:strong | self::e:a | self::e:u | self::e:span)"> 
     <xsl:choose> 
      <xsl:when test="current-grouping-key()"> 
       <p>       
        <xsl:apply-templates select="current-group()"/> 
       </p> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:apply-templates select="current-group()"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each-group> 
</xsl:template> 

そして、このような何か、それを呼び出す:

<xsl:template match="td"> 
    <xsl:copy> 
     <xsl:call-template name="wrapInPara"/> 
    </xsl:copy> 
</xsl:template> 

(あなたがそこに検討する必要がある以上<b><i>タグがあり、そしてそれはラッピング対象から除外されなければならない、ネストした表や画像以外のタグ可能性があり、そう私は願って見ることができるようにans可能であれば、同様のユースケースに対して変更することができます。

私はこのようなことをXSLT 1.0でやってみようとしていますが、同様の問題が示唆されているようなMuenchianグループ化方法を見ていますが、それを動作させることはできません。

大変助かりました!

答えて

2

これはあなたがそれを行う方法の1つです。実際には、 "para"要素ではない最初の兄弟で "para"要素をグループ化します。次に、wrapInParaノードは、 "para"以外の要素を選択し、pタグ内の次の "para"要素(キーを使用)をラップします。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*" /> 

    <xsl:key name="para" 
      match="text()|b|i|em|strong|a|u|span" 
      use="concat(generate-id(..), '|', generate-id(preceding-sibling::node()[not((self::text()|self::b|self::i|self::em|self::strong|self::a|self::u|self::span))][1]))" /> 

    <xsl:template name="wrapInPara"> 
     <xsl:apply-templates select="@class" /> 
     <!-- Handle `para` elements that have no preceding non-para nodes --> 
     <xsl:call-template name="groupInPara"> 
      <xsl:with-param name="group" select="key('para', concat(generate-id(), '|'))" /> 
     </xsl:call-template> 
     <xsl:for-each select="node()[not((self::text()|self::b|self::i|self::em|self::strong|self::a|self::u|self::span))]"> 
      <xsl:apply-templates select="." /> 
      <!-- Wrap any following `para` elements --> 
      <xsl:call-template name="groupInPara"> 
       <xsl:with-param name="group" select="key('para', concat(generate-id(..), '|', generate-id()))" /> 
      </xsl:call-template> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template name="groupInPara"> 
     <xsl:param name="group" /> 
     <xsl:if test="$group"> 
      <p> 
       <xsl:apply-templates select="$group" /> 
      </p> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="td"> 
     <xsl:copy> 
      <xsl:call-template name="wrapInPara"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
+0

SEは感謝の言葉を避けると言っていますが、それは失礼を感じます。とにかく完全性のためにコメントがありますが、間違って1.0に修正したバージョン2.0を残してしまっただけですが、完全に動作します。ありがとうございます! – Anders

関連する問題