0

ツリーを表す階層要素を変換したい。データは、次の形式でテーブル内に提供されます。

<?xml version="1.0" encoding="utf-16"?>
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
    <asx:values>
        <CONCEPTS>
            <item>
                <NO>1</NO>
                <NS_PREFIX>de-gaap-ci</NS_PREFIX>
                <XBRL_ID>bs.ass.monetary</XBRL_ID>
                <IS_TUPLE>false</IS_TUPLE>
                <FATHER_ID/>
                <CONTEXT_REF>D-2012</CONTEXT_REF>
                <UNIT_REF>EUR</UNIT_REF>
                <DECIMALS>2</DECIMALS>
                <PRECISION/>
                <IS_NIL>false</IS_NIL>
                <VALUE>12923.00-</VALUE>
            </item>
            <item>
                <NO>2</NO>
                <NS_PREFIX>de-gaap-ci</NS_PREFIX>
                <XBRL_ID>bs.ass.string</XBRL_ID>
                <IS_TUPLE>false</IS_TUPLE>
                <FATHER_ID/>
                <CONTEXT_REF>D-2012</CONTEXT_REF>
                <UNIT_REF/>
                <DECIMALS/>
                <PRECISION/>
                <IS_NIL>false</IS_NIL>
                <VALUE>Test String</VALUE>
            </item>
            <item>
                <NO>3</NO>
                <NS_PREFIX>de-gaap-ci</NS_PREFIX>
                <XBRL_ID>bs.ass.nil</XBRL_ID>
                <IS_TUPLE>false</IS_TUPLE>
                <FATHER_ID/>
                <CONTEXT_REF>D-2012</CONTEXT_REF>
                <UNIT_REF/>
                <DECIMALS/>
                <PRECISION/>
                <IS_NIL>true</IS_NIL>
                <VALUE/>
            </item>
            <item>
                <NO>4</NO>
                <NS_PREFIX>de-gaap-ci</NS_PREFIX>
                <XBRL_ID>bs.ass.tuple1</XBRL_ID>
                <IS_TUPLE>true</IS_TUPLE>
                <FATHER_ID/>
                <CONTEXT_REF>D-2012</CONTEXT_REF>
                <UNIT_REF/>
                <DECIMALS/>
                <PRECISION/>
                <IS_NIL>false</IS_NIL>
                <VALUE/>
            </item>
            <item>
                <NO>5</NO>
                <NS_PREFIX>de-gaap-ci</NS_PREFIX>
                <XBRL_ID>bs.ass.a</XBRL_ID>
                <IS_TUPLE>false</IS_TUPLE>
                <FATHER_ID>bs.ass.tuple1</FATHER_ID>
                <CONTEXT_REF>D-2012</CONTEXT_REF>
                <UNIT_REF/>
                <DECIMALS/>
                <PRECISION/>
                <IS_NIL>false</IS_NIL>
                <VALUE>Value for bs.ass.a</VALUE>
            </item>
            <item>
                <NO>6</NO>
                <NS_PREFIX>de-gaap-ci</NS_PREFIX>
                <XBRL_ID>bs.ass.b</XBRL_ID>
                <IS_TUPLE>false</IS_TUPLE>
                <FATHER_ID>bs.ass.tuple1</FATHER_ID>
                <CONTEXT_REF>D-2012</CONTEXT_REF>
                <UNIT_REF/>
                <DECIMALS/>
                <PRECISION/>
                <IS_NIL>false</IS_NIL>
                <VALUE>Value for bs.ass.b</VALUE>
            </item>
        </CONCEPTS>
        <CONTEXTS>
            <item>
                <ID>D-2012</ID>
                <SCHEME>http://www.rzf-nrw.de/Steuernummer</SCHEME>
                <IDENTIFIER>5117050051729</IDENTIFIER>
                <IS_INSTANT>false</IS_INSTANT>
                <DATE_A>2012-08-28</DATE_A>
                <DATE_B>2012-08-30</DATE_B>
            </item>
            <item>
                <ID>I-2012</ID>
                <SCHEME>http://www.rzf-nrw.de/Steuernummer</SCHEME>
                <IDENTIFIER>5117050051729</IDENTIFIER>
                <IS_INSTANT>true</IS_INSTANT>
                <DATE_A>2012-08-28</DATE_A>
                <DATE_B/>
            </item>
        </CONTEXTS>
        <UNITS>
            <item>
                <ID>EUR</ID>
                <MEASURE_NS>iso4217</MEASURE_NS>
                <MEASURE_VALUE>EUR</MEASURE_VALUE>
            </item>
                        (...)
        </UNITS>
        <NAMESPACES>
            <item>
                <PREFIX>de-gcd</PREFIX>
                <URI>http://www.xbrl.de/taxonomies/de-gcd-2011-09-14</URI>
                <IS_DEFAULT>false</IS_DEFAULT>
            </item>
                        (...)
        </NAMESPACES>
        <SCHEMAS>
            <item>
                <SCHEMA_REF>http://www.xbrl.de/taxonomies/de-gcd-2011-09-14.xsd</SCHEMA_REF>
            </item>
                        (...)
        </SCHEMAS>
    </asx:values>
</asx:abap>

この列IS_TUPLEは、この要素がツリー内の親ノードであることを示しています。XBRL_ID列内にこの父の を持つすべての要素は、この父FATHER_IDの子であると想定されています。したがって、列FATHER_IDが空の場合、ノードには親がありません。

これらの要素を XSLT で再帰的に処理したいと考えています。対象フォーマットは基本的にXMLであるXBRLです。これが私の試みです:

<xsl:template match="/">
<xbrl ...>
   <xsl:apply-templates select="/CONCEPTS/item">
      <xsl:with-param name="rec_father_node" select="/" />
   </xsl:apply-templates>
</xbrl>
</xsl:template>

<xsl:template name="tpl_concept" match="/CONCEPTS/item">

    <xsl:param name="rec_father_node"/>

    <xsl:variable name="rec_father_id" select="string($rec_father_node/XBRL_ID/text())"/>

    <xsl:variable name="father_id" select="string(*[local-name()='FATHER_ID'])"/>
    <xsl:variable name="is_tuple" select="string(*[local-name()='IS_TUPLE'])"/>     
    <xsl:variable name="ns_prefix" select="string(*[local-name()='NS_PREFIX'])"/>
    <xsl:variable name="xbrl_id" select="string(*[local-name()='XBRL_ID'])"/>
    <xsl:variable name="name" select="$xbrl_id"/>

    <xsl:if test="$is_tuple = 'false' and $rec_father_id = $father_id">

        <xsl:element name="{$name}">
                      (...)
        </xsl:element>
    </xsl:if>

    <xsl:if test="$is_tuple = 'true' and $rec_father_id = $father_id">
        <xsl:element name="{$name}">
            <xsl:choose>
                <xsl:when test="$is_nil = 'true'">
                    <xsl:attribute name="xsi:nil">true</xsl:attribute>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="/CONCEPTS/item">
                        <xsl:with-param name="rec_father_id" select="current()" />
                    </xsl:apply-templates>                  
                </xsl:otherwise>
            </xsl:choose>
        </xsl:element>
    </xsl:if>       
</xsl:template>

私の考えは次のとおりです。親ではないノードには、列内に '' の文字列値がありますFATHER_ID。したがって、ルート ノードをパラメーターに渡して、rec_father_nodeこの初期文字列を取得します。同じテンプレートの再帰呼び出しでは、パラメーターrec_father_nodeにこの父のノードが含まれているため、この父の を読み取ってXBRL_ID、列内にこの値を持つ要素のみを追加できますFATHER_ID

私の問題は次のとおりです。パラメーターはrec_father_node、再帰呼び出しによって渡された値を失います。値は常に、最初の<xsl:apply-templates .../>呼び出しによって渡されるルート ノードです。

再帰的なテンプレート呼び出しにパラメーターを渡す方法はありますか? または、一般的に、このフラットなテーブルをネストされた要素を持つ XML ノード ツリーに変換するにはどうすればよいでしょうか?

変換のターゲットは次のようになります (上記の例から名前を取得し、わかりやすくするために他のノードをいくつか追加しました)。

<?xml version="1.0" encoding="UTF-8"?>
<xbrl>
    <bs.ass.monetary>12923.00-</bs.ass.monetary>
    <bs.ass.string>Test String</bs.ass.string>
    <bs.ass.nil></bs.ass.nil>
    <bs.ass.tuple1>
        <bs.ass.a>Value for bs.ass.a</bs.ass.a>
        <bs.ass.b>Value for bs.ass.b</bs.ass.b>
    </bs.ass.tuple1>
</xbrl>

助けやコメントをありがとう!

4

1 に答える 1

1

あなたができることは、最初にFATHER_ID要素に基づいて「子」アイテムを検索するためのキーを定義することです。

<xsl:key name="children" match="item" use="FATHER_ID" />

まず、父親のいないアイテムを一致させることから始めますが

<xsl:apply-templates select="item[FATHER_ID='']"/>

次に、「タプル」であるアイテムの場合、それらを一致させ、それらの子をキーで再帰的に一致させることができます

<xsl:template match="item[IS_TUPLE='true']">
   <xsl:element name="{XBRL_ID}">
      <xsl:apply-templates select="key('children', XBRL_ID)" />
   </xsl:element>
</xsl:template>

また、非タプルに一致するアイテム要素用の別のテンプレートもあり、好きな値を出力します。

次の XSLT を試してください

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="children" match="item" use="FATHER_ID"/>

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

   <xsl:template match="CONCEPTS">
      <xbrl>
         <xsl:apply-templates select="item[FATHER_ID='']"/>
      </xbrl>
   </xsl:template>

   <xsl:template match="item[IS_TUPLE='true']">
      <xsl:element name="{XBRL_ID}">
         <xsl:apply-templates select="key('children', XBRL_ID)"/>
      </xsl:element>
   </xsl:template>

   <xsl:template match="item">
      <xsl:element name="{XBRL_ID}">
         <xsl:value-of select="VALUE" />
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

サンプルに適用すると、次のようになります。

<xbrl>
   <bs.ass.monetary>12923.00-</bs.ass.monetary>
   <bs.ass.string>Test String</bs.ass.string>
   <bs.ass.nil></bs.ass.nil>
   <bs.ass.tuple1>
      <bs.ass.a>Value for bs.ass.a</bs.ass.a>
      <bs.ass.b>Value for bs.ass.b</bs.ass.b>
   </bs.ass.tuple1>
</xbrl>
于 2012-08-31T10:30:12.387 に答える