2016-07-13 10 views
0

コード行をブロックにグループ化しようとすると、親のテキストが失われてしまい、その理由がわかりません。私は問題を修正し、私のグループセレクタに|text()を追加しようとしましたが、その後、私のcodeblock要素はありませんXSLT - グループ化と親のテキストの削除

XML

<body> 
    <ul> 
    <li>before 
     <filepath>one test</filepath> now some code: 
     <codeblock>1</codeblock> 
     <codeblock>2</codeblock> 
     after text</li> 
    </ul> 
    <section> 
    <title>Test2</title> 
    <p>qqqq</p> 
    <codeblock>1</codeblock> 
    <codeblock>2</codeblock> 
    <codeblock>3</codeblock> 
    </section> 
</body> 

XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

<xsl:template match="@*|node()"> 
    <xsl:choose> 
     <xsl:when test="./codeblock[1] or ./msgblock[1]"> 
      <xsl:call-template name="merge-codeblock"> 
       <xsl:with-param name="container" select="."/> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy> 
       <xsl:apply-templates select="@* | node()" /> 
      </xsl:copy> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template name="merge-codeblock"> 
    <xsl:param name="container"/>  
      <xsl:copy> 
       <xsl:for-each-group select="*" group-adjacent="boolean(self::codeblock or self::msgblock)"> 
        <xsl:choose> 
         <xsl:when test="current-grouping-key() and count(current-group()) gt 1"> 
          <xsl:element name="{name()}"> 
           <xsl:variable name="name" select="current-group()/node()" /> 
           <xsl:for-each select="current-group()/node()"> 
            <xsl:variable name="namee" select="current()" /> 
            <xsl:apply-templates select="current()" /> 
            <xsl:text>&#10;</xsl:text> 
           </xsl:for-each> 
          </xsl:element> 
         </xsl:when> 
         <xsl:otherwise> 
          <xsl:apply-templates select="current-group()" /> 
         </xsl:otherwise> 
        </xsl:choose> 
       </xsl:for-each-group> 
      </xsl:copy>   
</xsl:template> 

</xsl:stylesheet> 

現在の結果

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "dtd/task.dtd"><!--<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "dtd/task.dtd">--><body> 
    <ul> 
     <li><!-- not ok! I lost my li/text() --> 
     <filepath>one test</filepath> 
     <codeblock>1 
2 
</codeblock> 
     </li> 
    </ul> 
    <section> 
     <title>Test</title> 
     <p>fddsfsd</p> 
     <codeblock>fdsfds</codeblock> 
    </section> 
    <section> 
     <title>Test2</title> 
     <p>qqqq</p> 
     <codeblock>1 
2 
3 
</codeblock> 
    </section> 
</body> 

もう合併。

私は間違っていますか?

EDIT: マーティンの答えはLIの問題を修正しますが、私は残念ながら今の余分な私のコードブロックラインの前にスペースと最初のコードブロックの後にキャリッジリターンを持っている:

<codeblock> 
     1 
     2 
     3 
</codeblock> 

の代わりに:

<codeblock>1 
2 
3</codeblock> 

どのようにこれらを取り除くことができます、私はcurrent-group()内のスペースをまだ成功させずに削除しようとしました。

推奨編集は私を与える:

<codeblock> 

1 


2 


3 

    </codeblock> 

しかし、問題は奇妙な空白のまま。 current-group()には、空白スペースに改行を含む" ", <codeblock>, " ", <codeblock>, " ", <codeblock>, " "が含まれています。

+0

 <xsl:choose> <xsl:when test="current-grouping-key() and current-group()[self::*]"> <xsl:element name="{name(current-group()[self::*[1]][1])}"> <xsl:apply-templates select="current-group()"/> </xsl:element> </xsl:when> 

を簡素化することができますと仮定しますが、出力をしたいですか?そして、codeblock要素の中に要素があるのでしょうか?私は後者の場合、最も簡単なアプローチは 'グループ() "/>' –

+0

あなたのアイデアを試しましたが、まだ失敗します。別のアイデアがある場合に備えて、いくつかの詳細を投稿しました:) – Flag

+0

回答の編集を参照してください。 –

答えて

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" exclude-result-prefixes="xs" version="2.0"> 

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

    <xsl:template match="*[codeblock | msgblock]"> 
     <xsl:copy> 
      <xsl:for-each-group select="node()" 
       group-adjacent="boolean(self::text()[not(normalize-space())] | self::codeblock | self::msgblock)"> 
       <xsl:choose> 
        <xsl:when test="current-grouping-key() and current-group()[self::*]"> 
         <xsl:element name="{name(current-group()[self::*[1]][1])}"> 
          <xsl:apply-templates select="current-group()"/> 
         </xsl:element> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:apply-templates select="current-group()"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="codeblock | msgblock"> 
     <xsl:apply-templates/> 
    </xsl:template> 
</xsl:stylesheet> 

グループを考えると、テキストを保持し、私は正確にあなたが望む結果どのわからないとしてグループ化されたコンテンツを出力する部分を適応させる必要がある場合があります。ホワイトスペースとあなたの問題については

、あなたは、単にそれらのcodeblockmsgblock要素でプレーンテキストを持っている、あなたは

   <xsl:choose> 
        <xsl:when test="current-grouping-key() and current-group()[self::*]"> 
         <xsl:element name="{name(current-group()[self::*[1]][1])}"> 
          <xsl:value-of select="current-group()[self::*]" separator="&#10;"/> 
         </xsl:element> 
        </xsl:when> 
+0

もう一度、非常に良いアプローチ。私の最初のテストではうまくいっているようです。どうもありがとうございました! – Flag

+0

私は気付いた問題を表示するために質問を更新しましたが、今はあまり成功していないまま修正しようとしています。どんな助けもありがとう。 – Flag

関連する問題