使用XSLT的递归转换:表到树
我想转换表示树的层次元素。数据以以下格式提供在表格中:使用XSLT的递归转换:表到树,xslt,recursion,xslt-1.0,xbrl,Xslt,Recursion,Xslt 1.0,Xbrl,我想转换表示树的层次元素。数据以以下格式提供在表格中: <?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</N
<?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>
我的想法如下:没有父节点的节点在列father\u ID
中具有字符串值“”。因此,我将根节点传递给参数rec\u father\u node
,以获得这个初始字符串。通过对同一模板的递归调用,参数rec\u father\u node
包含此父节点,因此我可以读取此父节点的XBRL\u ID
,以便仅在列father\u ID
中添加具有此值的元素
我的问题如下:参数rec\u-father\u node
释放递归调用传递的值。该值始终是初始
调用传递的根节点
有没有办法将参数传递给递归模板调用?或者,一般来说,如何将这个平面表转换为包含嵌套元素的XML节点树
转换的目标应该如下所示(从上面的示例中选取名称,并添加一些其他节点以便于说明):
12923.00-
测试字符串
bs.ass.a的价值
bs.ass.b的值
谢谢你的帮助和评论 您可以首先定义一个键,根据“子”项的父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>
您还将有另一个用于item元素的模板,该模板将匹配非元组,它将输出您想要的任何值
尝试以下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>
12923.00-
测试字符串
bs.ass.a的价值
bs.ass.b的值
尽管将输入样本尽可能小总是好的,但如果输出样本与输入直接对应,也会更有帮助。谢谢好的,我更新了我想要转换为原始的源代码,并更新了想要的输出。我对你的回答发表评论。它基本上是有效的,但我仍然有一个问题。谢谢你迄今为止的帮助!现在更新了。由于某些原因,stackoverflow没有保存我的更改!我已经更新了我的答案,所以您现在应该可以获得预期的输出。
<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>