2016-08-10 4 views
1

ヘッダーでグループ化したいが、構造が論理でない場合、セクション分割は停止する。例えば、< h2>続いて< h4>。例を参照してください。 < h4>セクションが表示され、< h3>がない場合に表示されますが、動作しないようです。誰かが私を助けることができますか?私はxslt 2.0で作業します。非論理フラット構造を階層的にする

入力:

 

    <?xml version="1.0" encoding="UTF-8"?> 
    <document id="21" state="Schrijven" documentTypeName="News"> 
      <document track-changes="false" version="1"> 
      <section> 
        <h1>Title h1</h1> 
         <p>Some text</p> 
         <p/> 
        <h2>Title h2</h2> 
         <p>Some text</p> 
         <p/> 
        <h3>Title h3</h3> 
         <p>Some text</p> 
         <p/> 
        <h2>Title h2</h2> 
         <p>Some text</p> 
         <p/> 
        <h4>Title h4</h4> 
         <p>Some text</p> 
         <p/> 
      </section>   
      </document> 
     </document> 

出力

 

    <html> 
     <head> 
      <meta charset="UTF-8"/> 
     </head> 
     <body data-sws-documentkey="id-00021"> 
      <section class="level-newsitem"> 
      <h1 class="nieuws">Title h1</h1> 
      <p>Some text</p> 
      <p/> 
      <section class="level"> 
       <h2>Title h2</h2> 
       <p>Some text</p> 
       <p/> 
       <section class="level"> 
        <h3>Title h3</h3> 
        <p>Some text</p> 
        <p/> 
       </section> 
      </section> 
      <section class="level"> 
       <h2>Title h2</h2> 
       <p>Some text</p> 
       <p/> 
       <h4>Title h4</h4> 
       <p>Some text</p> 
       <p/> 
      </section> 
      </section> 
     </body> 
    </html> 

所望の出力

 

    <html> 
     <head> 
      <meta charset="UTF-8"/> 
     </head> 
     <body data-sws-documentkey="id-00021"> 
      <section class="level-newsitem"> 
      <h1 class="nieuws">Title h1</h1> 
      <p>Some text</p> 
      <p/> 
      <section class="level"> 
       <h2>Title h2</h2> 
       <p>Some text</p> 
       <p/> 
       <section class="level"> 
        <h3>Title h3</h3> 
        <p>Some text</p> 
        <p/> 
       </section> 
      </section> 
      <section class="level"> 
       <h2>Title h2</h2> 
       <p>Some text</p> 
       <p/> 
       <section class="level"> 
        <h4>Title h4</h4> 
        <p>Some text</p> 
        <p/> 
       </section> 
      </section> 
      </section> 
     </body> 
    </html> 

スタイルシート

 

    <?xml version="1.0" encoding="UTF-8"?> 

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     xmlns:cwc="urn:cwc" 
     xmlns:p1="urn:p1" 
     exclude-result-prefixes="xs cwc p1" 
     version="2.0"> 

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/> 
    <xsl:strip-space elements="document meta section div row"/> 

    <xsl:variable name="DocumentKey"> 
     <xsl:value-of select="concat('id-000', /document[1]/@id)"/> 
    </xsl:variable> 

    <xsl:variable name="DocSoort"> 
     <xsl:value-of select="/document/@documentTypeName"/> 
    </xsl:variable> 

    <xsl:template match="document"> 
     <html> 
      <head> 
       <meta charset="UTF-8"/> 
       <xsl:if test="./meta/description"> 
        <meta name="description"> 
        <xsl:attribute name="content"> 
         <xsl:value-of select="./meta/description"/> 
        </xsl:attribute> 
        </meta> 
       </xsl:if>  
       <title><xsl:value-of select="./naam"/></title> 
      </head> 
      <body data-sws-documentkey="{$DocumentKey}"> 
       <xsl:choose> 
        <xsl:when test="$DocSoort='Note'"> 
         <xsl:apply-templates mode="Note"/> 
        </xsl:when> 
        <xsl:when test="$DocSoort='News'"> 
         <xsl:apply-templates mode="News"/></xsl:when> 
       </xsl:choose> 
      </body>  
     </html> 
    </xsl:template> 

    <xsl:template match="h1" mode="#all"> 
    <xsl:variable name="DocSoorttitel"> 
     <xsl:choose> 
      <xsl:when test="$DocSoort='Note'">noteitem</xsl:when> 
      <xsl:when test="$DocSoort='News'">newsitem</xsl:when> 
     </xsl:choose> 
    </xsl:variable> 
    <xsl:variable name="count"> 
     <xsl:value-of select="count(preceding::h1)"/> 
    </xsl:variable> 
     <xsl:choose> 
      <xsl:when test="$count = 0"> 
       <xsl:copy> 
        <xsl:attribute name="class"> 
         <xsl:value-of select="$DocSoorttitel"/> 
        </xsl:attribute> 
        <xsl:apply-templates select="@*[name()!='class']" mode="#current"/> 
        <xsl:apply-templates mode="#current"/> 
       </xsl:copy> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:copy> 
        <xsl:apply-templates select="@*" mode="#current"/> 
        <xsl:apply-templates mode="#current"/> 
       </xsl:copy> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

    <xsl:template match="naam|meta|lastmodified" mode="#all"/> 

    <xsl:template match="*/document" mode="#all"> 
     <xsl:choose> 
      <xsl:when test="not(./section)"> 
       <section> 
        <xsl:attribute name="class"> 
         <xsl:value-of select="lower-case(concat('sws-', $DocSoort))"/> 
        </xsl:attribute> 
         <xsl:call-template name="groupingheaders"/> 
       </section>  
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:apply-templates mode="#current"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

    <xsl:template match="section" mode="#all"> 
     <section> 
      <xsl:attribute name="class"> 
       <xsl:value-of select="lower-case(concat('level-', $DocSoort))"/> 
      </xsl:attribute> 
      <xsl:call-template name="groupingheaders"/> 
     </section> 
    </xsl:template> 

    <xsl:template name="groupingheaders"> 
     <xsl:choose> 
      <xsl:when test="$DocSoort='Note'"> 
       <xsl:for-each-group select="*" group-starting-with="div[@class = 'letop'][parent::document or parent::section]|h2[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
        <xsl:choose> 
         <xsl:when test="current-group()[1]/self::div[@class = 'letop'][parent::document or parent::section]|current-group()[1]/self::h2[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
          <section class="level"> 
           <xsl:call-template name="group2"/> 
          </section> 
         </xsl:when> 
         <xsl:otherwise> 
          <xsl:apply-templates select="current-group()" mode="#current"/> 
         </xsl:otherwise> 
        </xsl:choose> 
       </xsl:for-each-group> 
      </xsl:when> 
      <xsl:when test="$DocSoort='News'"> 
       <xsl:for-each-group select="*" group-starting-with="h2[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
        <xsl:choose> 
         <xsl:when test="current-group()[1]/self::h2[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
          <section class="level"> 
           <xsl:call-template name="group2"/> 
          </section> 
         </xsl:when> 
         <xsl:otherwise> 
          <xsl:apply-templates select="current-group()" mode="#current"/> 
         </xsl:otherwise> 
        </xsl:choose> 
       </xsl:for-each-group> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:template> 

    <xsl:template name="group2"> 
     <xsl:for-each-group select="current-group()" group-starting-with="h3[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
      <xsl:choose> 
       <xsl:when test="current-group()[1]/self::h3[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
        <section class="level"> 
         <xsl:call-template name="group3"/> 
        </section> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:apply-templates select="current-group()" mode="#current"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:template> 

    <xsl:template name="group3"> 
     <xsl:for-each-group select="current-group()" group-starting-with="h4[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
      <xsl:choose> 
       <xsl:when test="current-group()[1]/self::h4[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
        <section class="level"> 
         <xsl:call-template name="group4"/> 
        </section> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:apply-templates select="current-group()" mode="#current"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:template> 

    <xsl:template name="group4"> 
     <xsl:for-each-group select="current-group()" group-starting-with="h5[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
      <xsl:choose> 
       <xsl:when test="current-group()[1]/self::h5[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
        <section class="level"> 
         <xsl:call-template name="group5"/> 
        </section> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:apply-templates select="current-group()" mode="#current"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:template> 

    <xsl:template name="group5"> 
     <xsl:for-each-group select="current-group()" group-starting-with="h6[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
      <xsl:choose> 
       <xsl:when test="current-group()[1]/self::h6[parent::document or parent::section][count(text()[normalize-space()]) > 0]"> 
        <section class="level"> 
         <xsl:apply-templates select="current-group()" mode="#current"/> 
        </section> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:apply-templates select="current-group()" mode="#current"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:template> 

    <xsl:template match="node()" mode="#all"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()" mode="#current"/> 
     </xsl:copy> 
    </xsl:template> 


    </xsl:stylesheet> 

答えて

1

定期的にグループ化が再帰関数で行うことができます場合は、

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:mf="http://example.com/mf" 
    exclude-result-prefixes="xs mf" 
    version="2.0"> 

    <xsl:output method="html" indent="yes"/> 

    <xsl:param name="prefix" as="xs:string" select="'h'"/> 
    <xsl:param name="max-level" as="xs:integer" select="6"/> 

    <xsl:function name="mf:group" as="node()*"> 
     <xsl:param name="nodes" as="node()*"/> 
     <xsl:param name="level" as="xs:integer"/> 
     <xsl:for-each-group select="$nodes" group-starting-with="*[local-name() eq concat($prefix, $level)]"> 
      <xsl:choose> 
       <xsl:when test="self::*[local-name() eq concat($prefix, $level)]"> 
        <section class="level"> 
         <xsl:apply-templates select="."/> 
         <xsl:sequence select="mf:group(current-group() except ., $level + 1)"/> 
        </section> 
       </xsl:when> 
       <xsl:when test="$level lt $max-level"> 
        <xsl:sequence select="mf:group(current-group(), $level + 1)"/> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:apply-templates select="current-group()"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:function> 

    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* , node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="*[h1 | h2 | h3 | h4 | h5 | h6]"> 
     <xsl:copy> 
      <xsl:sequence select="mf:group(*, 1)"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

あなたは多分他の要素とのためにテンプレートを追加する必要が

<document id="21" state="Schrijven" documentTypeName="News"> 

    <document track-changes="false" version="1"> 

     <section> 
     <section class="level"> 
      <h1>Title h1</h1> 
      <p>Some text</p> 
      <p></p> 
      <section class="level"> 
       <h2>Title h2</h2> 
       <p>Some text</p> 
       <p></p> 
       <section class="level"> 
        <h3>Title h3</h3> 
        <p>Some text</p> 
        <p></p> 
       </section> 
      </section> 
      <section class="level"> 
       <h2>Title h2</h2> 
       <p>Some text</p> 
       <p></p> 
       <section class="level"> 
        <h4>Title h4</h4> 
        <p>Some text</p> 
        <p></p> 
       </section> 
      </section> 
     </section> 
     </section>   

    </document> 

</document> 

<document id="21" state="Schrijven" documentTypeName="News"> 
    <document track-changes="false" version="1"> 
     <section> 
      <h1>Title h1</h1> 
      <p>Some text</p> 
      <p/> 
      <h2>Title h2</h2> 
      <p>Some text</p> 
      <p/> 
      <h3>Title h3</h3> 
      <p>Some text</p> 
      <p/> 
      <h2>Title h2</h2> 
      <p>Some text</p> 
      <p/> 
      <h4>Title h4</h4> 
      <p>Some text</p> 
      <p/> 
     </section>   
    </document> 
</document> 

を変換第1レベルは特殊な処理が必要であり、条件付きチェックで関数を拡張したり、第1レベルのテンプレートや関数を記述したりする必要があります。

関連する問題