2010-11-18 15 views
0

すでに処理されたノードの処理を回避する方法はありますか?すでに処理されたノードの処理をスキップ

入力XML

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <node1>node1.1</node1> 
    <node2>node2.1</node2> 
    <node2>node2.2</node2> 
    <node1>node1.2</node1> 
</root> 

XSLあなたが見ることができるように

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="root"> 
     <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match="node1"> 
     [Node1]:<xsl:value-of select="."></xsl:value-of> 
     <xsl:apply-templates select="following-sibling::node2"/> 
     [End node1] 
    </xsl:template> 

    <xsl:template match="node2"> 
      [Node2]:<xsl:value-of select="."></xsl:value-of> 
    </xsl:template> 

</xsl:stylesheet> 

出力

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

     [Node1]:node1.1 
      [Node2]:node2.1 
      [Node2]:node2.2 
     [End node1] 

      [Node2]:node2.1 

      [Node2]:node2.2 

     [Node1]:node1.2 
     [End node1] 

テンプレート<xsl:template match="node2">はnode2要素ごとに2回適用されます.1回はnode1テンプレートから、2回目はXSLTプロセッサがnode2要素を変換するときです。

xsl:template match="node2" 2回目の適用を避ける方法はありますか? node2の処理を、node1のテンプレートで処理した直後に停止する必要があります。

重要 この例は、より複雑な使用例のエミュレーションです。 これは、追加の制限があることを意味しています。ルート要素の処理用にテンプレートを変更することはできません。

要素の処理を停止するか、処理を他の要素に移動する方法があるかどうかを知りたいと思います。

+0

だから、とき* * 'node2'テンプレートを適用すべきか? 'node1'要素の前に現れる' node2'要素だけに? – AakashM

答えて

3

modeを使用して、使用するテンプレートの名前を付けることができます。

selectを持たないapply-templatesコールを処理して、何も出力しない空のキャッチオールノードを作成できます。あなたが必要なもの

次のスタイルシート出力:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="root"> 
     <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match="node1"> 
     [Node1]:<xsl:value-of select="."></xsl:value-of> 
     <xsl:apply-templates select="following-sibling::node2" mode="fromNode1"/> 
     [End node1] 
    </xsl:template> 

    <xsl:template match="node2" mode="fromNode1"> 
      [Node2]:<xsl:value-of select="."></xsl:value-of> 
    </xsl:template> 

    <xsl:template match="node2"></xsl:template> 
</xsl:stylesheet> 

注最後に空のモードレステンプレート、およびテンプレートに追加mode属性とapply-templatesを呼び出します。

+0

私はモードの強い解決策を考えていませんでした。 – annakata

+0

+1良い解決策です。 –

+0

これは 'node1'の前にグループ化されていないことに注意してください。したがって、ノード2は最終的には良い解決策のために1回以上 –

0

XSLTは状態を追跡せず、すべてのapply-templates、for-eachなどは潜在的に "冗長"な結果を生成しますが、これはスタイルシートのデザインにおいて全く問題になります。適切なテンプレートを変更して選択する必要があるノードを複数回「処理」するため、複数回処理されません。

あなたの例ではかなり些細なことですが、あなたの例はそれほど表象的ではないと言いました。問題がある場合は、より完全なものを投稿することをお勧めします。

1

このスタイルシート:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="text"/> 
    <xsl:key name="kNode2ByPrecedingNode1" match="node2" 
      use="generate-id(preceding-sibling::node1)"/> 
    <xsl:template match="root"> 
     <xsl:apply-templates select="node1"/> 
    </xsl:template> 
    <xsl:template match="node1"> 
     <xsl:value-of select="concat('[Node1]: ',.,'&#xA;')"/> 
     <xsl:apply-templates select="key('kNode2ByPrecedingNode1', 
             generate-id())"/> 
     <xsl:text>[End node1]&#xA;</xsl:text> 
    </xsl:template> 
    <xsl:template match="node2"> 
     <xsl:value-of select="concat('&#x9;[Node2]: ',.,'&#xA;')"/> 
    </xsl:template> 
</xsl:stylesheet> 

出力:

[Node1]: node1.1 
    [Node2]: node2.1 
    [Node2]: node2.2 
[End node1] 
[Node1]: node1.2 
[End node1] 

:2つの問題:あなたは何度もnode2以上を処理し、rootルールからすべてノードの子にテンプレートを適用すると、およびnode1ルールから;あなたのfollowing-sibling::node2式では、node2の後にはnode1が続きます。

は編集 :あなたはrootルールがテンプレートを適用する方法を変更することができないならば、あなたは、プロセスのためのモードを必要とproccessをスキップします:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="text"/> 
    <xsl:key name="kNode2ByPrecedingNode1" match="node2" 
      use="generate-id(preceding-sibling::node1)"/> 
    <xsl:template match="root"> 
     <xsl:apply-templates/> 
    </xsl:template> 
    <xsl:template match="node1"> 
     <xsl:value-of select="concat('[Node1]: ',.,'&#xA;')"/> 
     <xsl:apply-templates select="key('kNode2ByPrecedingNode1', 
             generate-id())" 
          mode="output"/> 
     <xsl:text>[End node1]&#xA;</xsl:text> 
    </xsl:template> 
    <xsl:template match="node2"/> 
    <xsl:template match="node2" mode="output"> 
     <xsl:value-of select="concat('&#x9;[Node2]: ',.,'&#xA;')"/> 
    </xsl:template> 
</xsl:stylesheet> 
+0

+1になる可能性があります。 –

関連する問題