使用XSLT将XML平面化为嵌套
在这件事上花了太多时间….“f$%” 希望你能分享你的经验。 我有来自外部数据库的源平面XML,其结构如下:使用XSLT将XML平面化为嵌套,xml,xslt-2.0,xslt-grouping,Xml,Xslt 2.0,Xslt Grouping,在这件事上花了太多时间….“f$%” 希望你能分享你的经验。 我有来自外部数据库的源平面XML,其结构如下: <?xml version="1.0" encoding="utf-8"?> <ns:MT_ActualCosts xmlns:ns="http://percite:scmaster/actual_costs"> <row> <EVENT_ID>106</EVENT_ID>
<?xml version="1.0" encoding="utf-8"?>
<ns:MT_ActualCosts xmlns:ns="http://percite:scmaster/actual_costs">
<row>
<EVENT_ID>106</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>9999</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-09 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>0001</TOTAL_AMOUNT_NET>
<RO_NUMBER>102808</RO_NUMBER>
</row>
<row>
<EVENT_ID>106</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24444</INVOICE_NUMBER>
<PLANT>0003</PLANT>
<ALLOCATION_AMOUNT>122</ALLOCATION_AMOUNT>
</row>
<row>
<EVENT_ID>109</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24458</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-09 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>0011</TOTAL_AMOUNT_NET>
<RO_NUMBER>102813</RO_NUMBER>
</row>
<row>
<EVENT_ID>109</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24458</INVOICE_NUMBER>
<PLANT>0003</PLANT>
<ALLOCATION_AMOUNT>11.1</ALLOCATION_AMOUNT>
</row>
<row>
<EVENT_ID>108</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24535</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-19 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>11</TOTAL_AMOUNT_NET>
<RO_NUMBER>102811</RO_NUMBER>
</row>
<row>
<EVENT_ID>108</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24535</INVOICE_NUMBER>
<PLANT>0002</PLANT>
<ALLOCATION_AMOUNT>11</ALLOCATION_AMOUNT>
</row>
<row>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-28 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>999999</TOTAL_AMOUNT_NET>
<RO_NUMBER>103063</RO_NUMBER>
</row>
<row>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<PLANT>0001</PLANT>
<ALLOCATION_AMOUNT>11.47</ALLOCATION_AMOUNT>
</row>
<row>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>2</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<PLANT>0001</PLANT>
<ALLOCATION_AMOUNT>11.53</ALLOCATION_AMOUNT>
</row>
</ns:MT_ActualCosts>
My requested Target Structure should be something like this:
[![enter image description here][1]][1]
I need to group under the Header segments RecordLine Segments of the same `EVENT_ID`.
Currently my XSLT can't create the needed structure.
this is my XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns0="http://percite:scmaster/actual_costs">
<xsl:output method="xml" indent="yes"/>
<!-- xsi:noNamespaceSchemaLocation="\\palnt03\palramnet-redirect$\IL-Users\My-Documents\nimrod_g\SAP\Projects\ScMaster\Finance\ActualCosts\development\xsd"> -->
<xsl:template match="/">
<ns0:MT_ActualCostPreNormalized>
<xsl:for-each select= "ns0:MT_ActualCosts/row">
<xsl:if test="LINE_NUMBER=0">
<Header>
<EVENT_ID><xsl:value-of select="EVENT_ID"></xsl:value-of>
</EVENT_ID>
<LINE_NUMBER>
<xsl:value-of select="LINE_NUMBER"/>
</LINE_NUMBER>
<INVOICE_NUMBER>
<xsl:value-of select="INVOICE_NUMBER"/>
</INVOICE_NUMBER>
<CURRENCY_CODE>
<xsl:value-of select="CURRENCY_CODE"/>
</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>
<xsl:value-of select="TOTAL_AMOUNT_NET"/>
</TOTAL_AMOUNT_NET>
<RO_NUMBER>
<xsl:value-of select="RO_NUMBER"/>
</RO_NUMBER>
<PLANT>
<xsl:value-of select="PLANT"/>
</PLANT>
<ALLOCATION_AMOUNT>
<xsl:value-of select="ALLOCATION_AMOUNT"/>
</ALLOCATION_AMOUNT>
</Header>
</xsl:if>
<xsl:if test="LINE_NUMBER!=0">
<RecordLine>
<EVENT_ID><xsl:value-of select="EVENT_ID"></xsl:value-of>
</EVENT_ID>
<LINE_NUMBER>
<xsl:value-of select="LINE_NUMBER"/>
</LINE_NUMBER>
<INVOICE_NUMBER>
<xsl:value-of select="INVOICE_NUMBER"/>
</INVOICE_NUMBER>
<CURRENCY_CODE>
<xsl:value-of select="CURRENCY_CODE"/>
</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>
<xsl:value-of select="TOTAL_AMOUNT_NET"/>
</TOTAL_AMOUNT_NET>
<RO_NUMBER>
<xsl:value-of select="RO_NUMBER"/>
</RO_NUMBER>
<PLANT>
<xsl:value-of select="PLANT"/>
</PLANT>
<ALLOCATION_AMOUNT>
<xsl:value-of select="ALLOCATION_AMOUNT"/>
</ALLOCATION_AMOUNT>
</RecordLine>
</xsl:if>
</xsl:for-each>
</ns0:MT_ActualCostPreNormalized>
</xsl:template>
</xsl:stylesheet>
[1]: http://i.stack.imgur.com/yklFq.jpg
106
0
9999
2015-02-09 00:00:00.0
美元
0001
102808
106
1.
24444
0003
当您编写要对元素进行分组的代码时,我想作为一个起点,您可以对每个组使用,而不是对每个使用:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:ns0="http://percite:scmaster/actual_costs">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<ns0:MT_ActualCostPreNormalized>
<xsl:for-each-group select="row" group-by="EVENT_ID">
<Header>
<xsl:apply-templates select="EVENT_ID, LINE_NUMBER, current-group()"/>
</Header>
</xsl:for-each-group>
</ns0:MT_ActualCostPreNormalized>
</xsl:template>
<xsl:template match="row">
<RecordLine>
<xsl:apply-templates/>
</RecordLine>
</xsl:template>
</xsl:transform>
您可以在apply templates
中的标题下列出您想要的更多元素,因为您使用的是XSLT 2.0,所以可以使用xsl:for each group
()按事件ID
分组
另外,使用可以处理所有不需要更改的元素
例如
XML输入
<ns:MT_ActualCosts xmlns:ns="http://percite:scmaster/actual_costs">
<row>
<EVENT_ID>106</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>9999</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-09 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>0001</TOTAL_AMOUNT_NET>
<RO_NUMBER>102808</RO_NUMBER>
</row>
<row>
<EVENT_ID>106</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24444</INVOICE_NUMBER>
<PLANT>0003</PLANT>
<ALLOCATION_AMOUNT>122</ALLOCATION_AMOUNT>
</row>
<row>
<EVENT_ID>109</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24458</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-09 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>0011</TOTAL_AMOUNT_NET>
<RO_NUMBER>102813</RO_NUMBER>
</row>
<row>
<EVENT_ID>109</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24458</INVOICE_NUMBER>
<PLANT>0003</PLANT>
<ALLOCATION_AMOUNT>11.1</ALLOCATION_AMOUNT>
</row>
<row>
<EVENT_ID>108</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24535</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-19 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>11</TOTAL_AMOUNT_NET>
<RO_NUMBER>102811</RO_NUMBER>
</row>
<row>
<EVENT_ID>108</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24535</INVOICE_NUMBER>
<PLANT>0002</PLANT>
<ALLOCATION_AMOUNT>11</ALLOCATION_AMOUNT>
</row>
<row>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-28 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>999999</TOTAL_AMOUNT_NET>
<RO_NUMBER>103063</RO_NUMBER>
</row>
<row>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<PLANT>0001</PLANT>
<ALLOCATION_AMOUNT>11.47</ALLOCATION_AMOUNT>
</row>
<row>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>2</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<PLANT>0001</PLANT>
<ALLOCATION_AMOUNT>11.53</ALLOCATION_AMOUNT>
</row>
</ns:MT_ActualCosts>
<ns:MT_ActualCostPreNormalized xmlns:ns="http://percite:scmaster/actual_costs">
<Header>
<EVENT_ID>106</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>9999</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-09 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>0001</TOTAL_AMOUNT_NET>
<RO_NUMBER>102808</RO_NUMBER>
<RecordLine>
<EVENT_ID>106</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24444</INVOICE_NUMBER>
<PLANT>0003</PLANT>
<ALLOCATION_AMOUNT>122</ALLOCATION_AMOUNT>
</RecordLine>
</Header>
<Header>
<EVENT_ID>108</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24535</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-19 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>11</TOTAL_AMOUNT_NET>
<RO_NUMBER>102811</RO_NUMBER>
<RecordLine>
<EVENT_ID>108</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24535</INVOICE_NUMBER>
<PLANT>0002</PLANT>
<ALLOCATION_AMOUNT>11</ALLOCATION_AMOUNT>
</RecordLine>
</Header>
<Header>
<EVENT_ID>109</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24458</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-09 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>0011</TOTAL_AMOUNT_NET>
<RO_NUMBER>102813</RO_NUMBER>
<RecordLine>
<EVENT_ID>109</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24458</INVOICE_NUMBER>
<PLANT>0003</PLANT>
<ALLOCATION_AMOUNT>11.1</ALLOCATION_AMOUNT>
</RecordLine>
</Header>
<Header>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-28 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>999999</TOTAL_AMOUNT_NET>
<RO_NUMBER>103063</RO_NUMBER>
<RecordLine>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<PLANT>0001</PLANT>
<ALLOCATION_AMOUNT>11.47</ALLOCATION_AMOUNT>
</RecordLine>
<RecordLine>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>2</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<PLANT>0001</PLANT>
<ALLOCATION_AMOUNT>11.53</ALLOCATION_AMOUNT>
</RecordLine>
</Header>
</ns:MT_ActualCostPreNormalized>
106
0
9999
2015-02-09 00:00:00.0
美元
0001
102808
106
1.
24444
0003
丹尼尔,谢谢你的解决方案。似乎在某个地方,由于某种原因,数据开始混乱。看看EVENT_ID=105。嗨,马丁,谢谢你的代码。如何消除行数为0的行,因为它们表示我不想包含在记录行中的标题段。(保持数据完整性)如果您根本不想对它们进行分组,请将
更改为
。如果您想按事件ID将它们分组,但不想将它们作为记录行包含在标题元素中,那么请将
更改为
嗨,我相信复制的原因是它复制了行号“0”也表示记录行中的标题。在这种情况下,您可以将内部
更改为
或
。如果你仍然有问题,然后考虑编辑你的问题,并显示出你想要的结果作为一个代码样本,恐怕屏幕截图不足以告诉我们你想包括哪些元素,哪些不是。马丁,我尽我最大的努力(在四方限制),以添加一些MROE数据在我的箱子。希望这可以帮助…
<ns:MT_ActualCostPreNormalized xmlns:ns="http://percite:scmaster/actual_costs">
<Header>
<EVENT_ID>106</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>9999</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-09 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>0001</TOTAL_AMOUNT_NET>
<RO_NUMBER>102808</RO_NUMBER>
<RecordLine>
<EVENT_ID>106</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24444</INVOICE_NUMBER>
<PLANT>0003</PLANT>
<ALLOCATION_AMOUNT>122</ALLOCATION_AMOUNT>
</RecordLine>
</Header>
<Header>
<EVENT_ID>108</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24535</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-19 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>11</TOTAL_AMOUNT_NET>
<RO_NUMBER>102811</RO_NUMBER>
<RecordLine>
<EVENT_ID>108</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24535</INVOICE_NUMBER>
<PLANT>0002</PLANT>
<ALLOCATION_AMOUNT>11</ALLOCATION_AMOUNT>
</RecordLine>
</Header>
<Header>
<EVENT_ID>109</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24458</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-09 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>0011</TOTAL_AMOUNT_NET>
<RO_NUMBER>102813</RO_NUMBER>
<RecordLine>
<EVENT_ID>109</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24458</INVOICE_NUMBER>
<PLANT>0003</PLANT>
<ALLOCATION_AMOUNT>11.1</ALLOCATION_AMOUNT>
</RecordLine>
</Header>
<Header>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>0</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<INVOICE_DATE>2015-02-28 00:00:00.0</INVOICE_DATE>
<CURRENCY_CODE>USD</CURRENCY_CODE>
<TOTAL_AMOUNT_NET>999999</TOTAL_AMOUNT_NET>
<RO_NUMBER>103063</RO_NUMBER>
<RecordLine>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<PLANT>0001</PLANT>
<ALLOCATION_AMOUNT>11.47</ALLOCATION_AMOUNT>
</RecordLine>
<RecordLine>
<EVENT_ID>171</EVENT_ID>
<LINE_NUMBER>2</LINE_NUMBER>
<INVOICE_NUMBER>24645</INVOICE_NUMBER>
<PLANT>0001</PLANT>
<ALLOCATION_AMOUNT>11.53</ALLOCATION_AMOUNT>
</RecordLine>
</Header>
</ns:MT_ActualCostPreNormalized>