2017-05-23 5 views
0

私は他の場所からインポートする必要のある奇妙なXMLを取得しました。構造は、この例のようなものです:あなたが見るXSLT:いくつかのタグを別のタグで囲みます。

<INVOICE> 
    <HEADER_DATA_1> 
    <HEADER_DATA_ITEM_1>foo</HEADER_DATA_ITEM_1> 
    <HEADER_DATA_ITEM_2>bar</HEADER_DATA_ITEM_2> 
    </HEADER_DATA_1> 
    <HEADER_DATA_2> 
    <HEADER_DATA_ITEM_3>foo</HEADER_DATA_ITEM_3> 
    <HEADER_DATA_ITEM_4>bar</HEADER_DATA_ITEM_4> 
    </HEADER_DATA_2> 
    <HEADER_DATA_3> 
    <HEADER_DATA_ITEM_5>foo</HEADER_DATA_ITEM_5> 
    <HEADER_DATA_ITEM_6>bar</HEADER_DATA_ITEM_6> 
    </HEADER_DATA_3> 

    <POSITION_DATA_1> 
    <POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1> 
    <POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2> 
    </POSITION_DATA_1> 
    <POSITION_DATA_2> 
    <POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3> 
    <POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4> 
    </POSITION_DATA_2> 
    [...] 
    <POSITION_DATA_8> 
    <POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15> 
    <POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16> 
    </POSITION_DATA_8> 

    <POSITION_DATA_1> 
    <POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1> 
    <POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2> 
    </POSITION_DATA_1> 
    <POSITION_DATA_2> 
    <POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3> 
    <POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4> 
    </POSITION_DATA_2> 
    [...] 
    <POSITION_DATA_8> 
    <POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15> 
    <POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16> 
    </POSITION_DATA_8> 

    <POSITION_DATA_1> 
    <POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1> 
    <POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2> 
    </POSITION_DATA_1> 
    <POSITION_DATA_2> 
    <POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3> 
    <POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4> 
    </POSITION_DATA_2> 
    [...] 
    <POSITION_DATA_8> 
    <POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15> 
    <POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16> 
    </POSITION_DATA_8> 

</INVOICE> 

ように、請求書objektは、いくつかの単一のヘッダデータと、いくつかの位置データで構成され、いくつかの複数の位置を有することができます。しかし、残念ながら、これを輸出した人たちは、ポジションデータの周りに適切なタグをラップするのを忘れてしまった。だから私は、最終的なコードは次のようになりますように、それを修正したい:

<INVOICE> 
    <HEADER_DATA_1> 
    <HEADER_DATA_ITEM_1>foo</HEADER_DATA_ITEM_1> 
    <HEADER_DATA_ITEM_2>bar</HEADER_DATA_ITEM_2> 
    </HEADER_DATA_1> 
    <HEADER_DATA_2> 
    <HEADER_DATA_ITEM_3>foo</HEADER_DATA_ITEM_3> 
    <HEADER_DATA_ITEM_4>bar</HEADER_DATA_ITEM_4> 
    </HEADER_DATA_2> 
    <HEADER_DATA_3> 
    <HEADER_DATA_ITEM_5>foo</HEADER_DATA_ITEM_5> 
    <HEADER_DATA_ITEM_6>bar</HEADER_DATA_ITEM_6> 
    </HEADER_DATA_3> 

    <POSITION> 
    <POSITION_DATA_1> 
     <POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1> 
     <POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2> 
    </POSITION_DATA_1> 
    <POSITION_DATA_2> 
     <POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3> 
     <POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4> 
    </POSITION_DATA_2> 
    [...] 
    <POSITION_DATA_8> 
     <POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15> 
     <POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16> 
    </POSITION_DATA_8> 
    </POSITION> 

    <POSITION> 
    <POSITION_DATA_1> 
     <POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1> 
     <POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2> 
    </POSITION_DATA_1> 
    <POSITION_DATA_2> 
     <POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3> 
     <POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4> 
    </POSITION_DATA_2> 
    [...] 
    <POSITION_DATA_8> 
     <POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15> 
     <POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16> 
    </POSITION_DATA_8> 
    </POSITION> 

    <POSITION> 
    <POSITION_DATA_1> 
     <POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1> 
     <POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2> 
    </POSITION_DATA_1> 
    <POSITION_DATA_2> 
     <POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3> 
     <POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4> 
    </POSITION_DATA_2> 
    [...] 
    <POSITION_DATA_8> 
     <POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15> 
     <POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16> 
    </POSITION_DATA_8> 
    </POSITION> 
</INVOICE> 

はそれがよりさらに悪いことに、いくつかの要素は、特にPOSITION_DATA_1要素はオプションです。少なくともPOSITION_DATA_2とPOSITION_DATA_8は必須です。私は(おそらく)欠けているPOSITION_DATA_1タグを次のように修正しました:

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

    <xsl:template match="POSITION_DATA_2[not(preceding-sibling::POSITION_DATA_1)]"> 
    <xsl:element name="POSITION_DATA_1"/> 
    <xsl:call-template name="identity"/> 
    </xsl:template> 

これは欠けている場合に挿入します。私の主な目標は、解決策をthis threadから適応させようとしました。試したルールは次のようになります。

<xsl:template match="INVOICE"> 
    <xsl:copy> 
     <xsl:apply-templates select="HEADER_DATA_1|HEADER_DATA_2|HEADER_DATA_3"/> 
     <POSITION> 
      <xsl:apply-templates select="POSITION_DATA_1|POSITION_DATA_2|POSITION_DATA_3|POSITION_DATA_4|POSITION_DATA_5|POSITION_DATA_6|POSITION_DATA_7|POSITION_DATA_8"/> 
     </POSITION> 
    </xsl:copy> 
</xsl:template> 

これは一致しません。すべての位置に1つのPOSITIONタグしかラップしません。助言がありますか?

答えて

0

は、あなたができる、すべての項目を中心に含むタグをラップするために、その後、前POSITION_DATA_1

によってPOSITION_DATA_2POSITION_DATA_8に要素グループへの鍵を使用することを検討してくださいテンプレートPOSITION_DATA_1を持っているだけで、キーを使用して他のすべてのアイテムを折り返すことができます。

<xsl:template match="POSITION_DATA_1"> 
    <POSITION> 
     <xsl:call-template name="identity" /> 
     <xsl:apply-templates select="key('pos', generate-id())" /> 
    </POSITION> 
    </xsl:template> 

このXSLTあなたがXSLT 2.0を使用することができる場合、これは、位置のグループ化を使用して達成される

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:key name="pos" 
      match="*[starts-with(local-name(), 'POSITION_DATA_') and not(self::POSITION_DATA_1)]" 
      use="generate-id(preceding-sibling::POSITION_DATA_1[1])" /> 

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

    <xsl:template match="INVOICE"> 
    <xsl:copy> 
     <xsl:apply-templates select="HEADER_DATA_1|HEADER_DATA_2|HEADER_DATA_3"/> 
     <xsl:apply-templates select="POSITION_DATA_1"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="POSITION_DATA_1"> 
    <POSITION> 
     <xsl:call-template name="identity" /> 
     <xsl:apply-templates select="key('pos', generate-id())" /> 
    </POSITION> 
    </xsl:template> 
</xsl:stylesheet> 
0

試してみてください:あなたの偉大なアイデアを

<xsl:template match="INVOICE"> 
    <xsl:for-each-group select="*" group-starting-with="POSITION_DATA_1 | POSITION_DATA_2[not(preceding-sibling::*[1][self::POSITION_DATA_1]"> 
    <xsl:choose> 
     <xsl:when test="starts-with(local-name(), 'POSITION'> 
     <POSITION> 
      <xsl:copy-of select="current-group()"/> 
     </POSITION> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:copy-of select="current-group()"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:for-each-group> 
</xsl:template> 
0

みんなありがとうを! 私は最終的にMichael Kaysの答えに適応しました。今すぐ最終的な解決策を発表する時間:

<xsl:template match="INVOICE"> 
    <xsl:for-each-group select="*" group-starting-with="POSITION_DATA_1 | POSITION_DATA_2[not(preceding-sibling::POSITION_DATA_1)]"> 
     <xsl:choose> 
      <!-- Do no wrap the header data group --> 
      <xsl:when test="starts-with(local-name(), 'HEADER_DATA_1')"> 
       <xsl:apply-templates select="current-group()"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <POSITION> 
        <xsl:apply-templates select="current-group()"/> 
       </POSITION> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each-group> 
</xsl:template> 
関連する問題