2017-12-06 21 views
0

次のようなxmlがあります。1)データノードの値をヘッダーに移動したい場合は属性名に一致するか、2)可能であれば、xsl tranformを使用するヘッダー内の既存のノードと同じです。どんな助けでも大歓迎です。親ノード間にxmlノードを移動して重複を削除する - xslt 2.0

初期のxml:

<HEADER> 
    <KEY name="child1" value="value1" /> 
    <KEY name="child2" value="value2" /> 
    <KEY name="child3" value="value3" /> 
    <KEY name="child4" value="value4" /> 
</HEADER> 
<DATA> 
    <KEY name="child1" value="value1.data" /> 
    <KEY name="child3" value="value3.data" /> 
    <KEY name="child5" value="value5" /> 
    <KEY name="child7" value="value7" /> 
</DATA> 

子供5は、変換後、結果は...移動するためのノードである場合:

<HEADER> 
    <KEY name="child1" value="value1" /> 
    <KEY name="child2" value="value2" /> 
    <KEY name="child3" value="value3" /> 
    <KEY name="child4" value="value4" /> 
    <KEY name="child5" value="value5" /> 
</HEADER> 
<DATA> 
    <KEY name="child7" value="value7" /> 
</DATA> 

現在のxsl:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output omit-xml-declaration="no" method="xml" indent="yes" /> 

    <!-- <xsl:variable name="ReplaceLiveDate" select="false()" /> --> 
    <xsl:variable name="ReplaceLiveDate" select="true()" /> 

    <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" /> 
    <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" /> 

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

    <!-- in HEADER: output ROLE sorted by @name --> 
    <xsl:template match="HEADER"> 
     <xsl:copy> 
      <xsl:apply-templates select="KEY"> 
       <xsl:sort select="translate(@name, $smallcase, $uppercase)" order="ascending" /> 
       <!-- <xsl:sort select="@name" /> --> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <!-- in DATA: output KEY sorted by @name --> 
    <xsl:template match="DATA"> 
     <xsl:copy> 
      <xsl:apply-templates select="KEY"> 
       <xsl:sort select="translate(@name, $smallcase, $uppercase)" order="ascending" /> 
       <!-- <xsl:sort select="@name" /> --> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

Iノードを削除するには以下の手順を実行しますが、ノードがヘッダセクションに存在する場合にのみ行う方法は不明です

<!-- remove processing nodes --> 
<xsl:template match="KEY[starts-with(@name, 'child1')]"/> 

答えて

1

は、その変換を行うための多くの方法があるが、この場合には、私はスマート1は、単純化のために簡単に説明

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="2.0"> 
    <xsl:output omit-xml-declaration="no" method="xml" indent="yes" /> 

    <!-- <xsl:variable name="ReplaceLiveDate" select="false()" /> --> 
    <xsl:variable name="ReplaceLiveDate" select="true()" /> 

    <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" /> 
    <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" /> 

    <!-- index all the KEY element of the HEADER --> 
    <xsl:key name='head' match='HEADER/KEY' use='@name' /> 


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


    <xsl:template match='HEADER'> 
     <xsl:copy> 
      <!-- move the child5 'KEY element' under the header --> 
      <xsl:copy-of select="//DATA/KEY[@name = 'child5']"/> 
      <!-- apply to childs --> 
      <xsl:apply-templates select="KEY"> 
       <xsl:sort select="translate(@name, $smallcase, $uppercase)" order="ascending" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <!-- delete key nodes duplicated in Header, that is elments not indexed by the 'head' key --> 
    <xsl:template match="DATA/KEY[key('head',@name)]"> 
    </xsl:template> 

    <!-- delete the node to be moved --> 
    <xsl:template match="DATA/KEY[@name = 'child5']" /> 

</xsl:stylesheet> 

ためhereを参照してくださいキーがを特徴とXSLTを使用することであると思います上記のスタイルシートはアルファベット順にヘッダキーをソートしません。本当に必要な場合はperform-sortが必要です。

私はあなたのオリジナルのスタイルシートを可能な限り保管しようとしましたが、そのような方法で他の解決策は見つけられませんでした。あなたは@name属性でソートキー

<xsl:template match='HEADER'> 

    <xsl:variable name='unsorted_keys'> 
     <xsl:copy-of select="//DATA/KEY[@name = 'child5']"/> 
     <!-- apply to childs --> 
     <xsl:apply-templates select="KEY"> 
     </xsl:apply-templates>   
    </xsl:variable> 

    <xsl:copy>  
     <!-- make sure to copy HEADER attributes --> 
     <xsl:apply-templates select='@*'/> 

     <!-- perform sort --> 
     <xsl:perform-sort select="$unsorted_keys/KEY"> 
      <xsl:sort select="translate(@name, $smallcase, $uppercase)" order="ascending" /> 
     </xsl:perform-sort>   
    </xsl:copy> 
</xsl:template> 

希望をしたい場合、これは援助のため

+0

感謝を助けテンプレート以下

。私は今、移動と削除機能が働いているが、私はperform-sort関数が不明です。私は単純にperform-sortノードでソート文をラップする必要がありますか?私はこれを最後に置いていますか?例に示すように変数が必要ですか? さらに、私のすべての並べ替えをこの実行並べ替えの形式にすることをお勧めしますか? – mike

+0

はい、perform-sort_1-stylesheet.xslの例でperform-sortリンクを使用できます。 _generated_ノードを変数に保存し、perform-sortを実行すると、 ''命令でソートされたノードが表示されます – gtosto

+0

@mikeソートされた出力を得るために答えを更新するだけです – gtosto

関連する問題