2010-11-25 3 views
1

キーを使わずにひどく悪いxsltを書くことができますが、それはかなり遅くて面倒です。誰も私は次のXMLファイルを期待どおりの結果にきれいに変換する方法を知っていますか?ありがとう!キーを使用してこれを変換する方法

入力:

<testExecution> 
    <test> 
     <test.1/> 
     <test.2/> 
     <test.3/> 
    </test> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <executor> 
     <executor.1/> 
     <executor.2/> 
     <executor.3/> 
    </executor> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <invoker> 
     <invoker.1/> 
     <invoker.2/> 
     <invoker.3/> 
    </invoker> 
    <recipient> 
     <recipient.1/> 
     <recipient.2/> 
     <recipient.3/> 
    </recipient> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
</testExecution> 

結果:

<testExecution> 
    <test> 
     <test.1/> 
     <test.2/> 
     <test.3/> 
    </test> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <people> 
     <importantPeople> 
      <executor> 
       <executor.1/> 
       <executor.2/> 
       <executor.3/> 
      </executor> 
      <comment> 
       <comment.1/> 
       <comment.2/> 
       <comment.3/> 
      </comment> 
      <comment> 
       <comment.1/> 
       <comment.2/> 
       <comment.3/> 
      </comment> 
     </importantPeople> 
     <invoker> 
      <invoker.1/> 
      <invoker.2/> 
      <invoker.3/> 
     </invoker> 
    </people> 
    <recipient> 
     <recipient.1/> 
     <recipient.2/> 
     <recipient.3/> 
    </recipient> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
</testExecution> 
+0

良い質問、+1。アイデンティティルールを使用してオーバーライドし、次の 'comments'にキーを使用する伝統的なXSLTソリューションについては、私の答えを参照してください。 –

答えて

4

このスタイルシート:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="kElementByTest" match="invoker|recipient" 
      use="generate-id(preceding-sibling::test[1])"/> 
    <xsl:template match="node()|@*" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()[1]|@*"/> 
     </xsl:copy> 
     <xsl:apply-templates select="following-sibling::node()[1]"/> 
    </xsl:template> 
    <xsl:template match="executor"> 
     <xsl:variable name="vFollowing" 
         select="key('kElementByTest', 
            generate-id(preceding-sibling::test[1]))"/> 
     <people> 
      <importantPeople> 
       <xsl:call-template name="identity"/> 
      </importantPeople> 
      <xsl:apply-templates select="$vFollowing/self::invoker" 
            mode="copy"/> 
     </people> 
     <xsl:apply-templates select="$vFollowing/self::recipient" 
          mode="copy"/> 
    </xsl:template> 
    <xsl:template match="invoker"/> 
    <xsl:template match="recipient"/> 
    <xsl:template match="node()" mode="copy"> 
     <xsl:call-template name="identity"/> 
    </xsl:template> 
</xsl:stylesheet> 

出力:

<testExecution> 
    <test> 
     <test.1></test.1> 
     <test.2></test.2> 
     <test.3></test.3> 
    </test> 
    <comment> 
     <comment.1></comment.1> 
     <comment.2></comment.2> 
     <comment.3></comment.3> 
    </comment> 
    <people> 
     <importantPeople> 
      <executor> 
       <executor.1></executor.1> 
       <executor.2></executor.2> 
       <executor.3></executor.3> 
      </executor> 
      <comment> 
       <comment.1></comment.1> 
       <comment.2></comment.2> 
       <comment.3></comment.3> 
      </comment> 
      <comment> 
       <comment.1></comment.1> 
       <comment.2></comment.2> 
       <comment.3></comment.3> 
      </comment> 
     </importantPeople> 
     <invoker> 
      <invoker.1></invoker.1> 
      <invoker.2></invoker.2> 
      <invoker.3></invoker.3> 
     </invoker> 
    </people> 
    <recipient> 
     <recipient.1></recipient.1> 
     <recipient.2></recipient.2> 
     <recipient.3></recipient.3> 
    </recipient> 
    <comment> 
     <comment.1></comment.1> 
     <comment.2></comment.2> 
     <comment.3></comment.3> 
    </comment> 
    <comment> 
     <comment.1></comment.1> 
     <comment.2></comment.2> 
     <comment.3></comment.3> 
    </comment> 
</testExecution> 

:ファイングレイントラバーサル。 "このテストのためだけの"キーは以下の通りです。 "このレベルを閉じる"ための空のテンプレート。プッシュスタイル "処理を続ける"モード。それは完全な "プルスタイル"の "マークの前にprevius"に一致する可能性があります。

+0

素晴らしいおかげで! – user364939

+0

@ user364939:あなたは幸せです! –

1

この変換は、識別ルールを使用して優先します。 executorの直後のコメントは、key()機能を使用して取得されます。 executor,invokerおよびcommentの直後に、executorモードpeopleという名前でコピーされます。通常、匿名モードでは、これらは彼らに二度目のコピーを避けるために、空のテンプレートにマッチしています

<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:key name="kExecComments" match= 
    "comment 
      [preceding-sibling::* 
       [not(self::comment)][1] 
         [self::executor] 
      ]" 
    use="generate-id(preceding-sibling::executor[1])"/> 

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

<xsl:template match="executor"> 
    <people> 
    <importantPeople> 
     <xsl:apply-templates mode="people" 
     select=".|key('kExecComments', generate-id())"/> 
    </importantPeople> 
    <xsl:apply-templates mode="people" select= 
    "following-sibling::invoker"/> 
    </people> 
</xsl:template> 

<xsl:template match="executor|comment|invoker" 
     mode="people"> 
    <xsl:call-template name="identity"/> 
</xsl:template> 

<xsl:template match= 
    "invoker | 
    comment 
      [preceding-sibling::* 
       [not(self::comment)][1] 
         [self::executor] 
      ]"/> 

</xsl:stylesheet> 

提供されるXML文書に適用された場合:

<testExecution> 
    <test> 
     <test.1/> 
     <test.2/> 
     <test.3/> 
    </test> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <executor> 
     <executor.1/> 
     <executor.2/> 
     <executor.3/> 
    </executor> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <invoker> 
     <invoker.1/> 
     <invoker.2/> 
     <invoker.3/> 
    </invoker> 
    <recipient> 
     <recipient.1/> 
     <recipient.2/> 
     <recipient.3/> 
    </recipient> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
</testExecution> 

募集を生成し、正しい結果

<testExecution> 
    <test> 
     <test.1/> 
     <test.2/> 
     <test.3/> 
    </test> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <people> 
     <importantPeople> 
     <executor> 
      <executor.1/> 
      <executor.2/> 
      <executor.3/> 
     </executor> 
     <comment> 
      <comment.1/> 
      <comment.2/> 
      <comment.3/> 
     </comment> 
     <comment> 
      <comment.1/> 
      <comment.2/> 
      <comment.3/> 
     </comment> 
     </importantPeople> 
     <invoker> 
     <invoker.1/> 
     <invoker.2/> 
     <invoker.3/> 
     </invoker> 
    </people> 
    <recipient> 
     <recipient.1/> 
     <recipient.2/> 
     <recipient.3/> 
    </recipient> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
    <comment> 
     <comment.1/> 
     <comment.2/> 
     <comment.3/> 
    </comment> 
</testExecution> 
関連する問題