使用XSLT连接相同类型的数据
我想用XSLT连接相同类型的所有数据。我有以下XML:使用XSLT连接相同类型的数据,xslt,Xslt,我想用XSLT连接相同类型的所有数据。我有以下XML: <ZE1MARAM> <ZE1KONDM SEGMENT="1"> <VKORG>NL01</VKORG> <KONDART>VKP0</KONDART> <BEGINDATUM>99991231</BEGINDATUM> <EN
<ZE1MARAM>
<ZE1KONDM SEGMENT="1">
<VKORG>NL01</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NL01</KONDWERT>
<MENGE> 70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE> 70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKA0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE> 33.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
</ZE1MARAM>
NL01
VKP0
99991231
20120605
NL01
70
欧元
NLWS
VKP0
99991231
20120605
NLWS
70
欧元
NLWS
VKA0
99991231
20120605
NLWS
33
欧元
因此,结果xml中具有相同VKORG值的每个ZE1KONDM都必须附加到相同的元素。所以结果是这样的:
<result>
<prices value="NL01">
<price type="VKP0">
70.00
</price>
</prices>
<prices value="NLWS">
<price type="VKP0">
70.00
</price>
<price type="VKA0">
55.00
</price>
</prices>
<xsl:key name="myKey" match="ZE1KONDM" use="normalize-space(VKORG)" />
<xsl:for-each select="ZE1KONDM">
<xsl:choose>
<xsl:when test="KONDART='VKP0'">
<xsl:element name="prices">
<xsl:element name="price">
<xsl:value-of select="key('myKey', normalize-space(VKORG))/MENGE"/>
</xsl:element>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:for-each>
70
70
55
我试着用钥匙工作,并做了类似的事情:
<result>
<prices value="NL01">
<price type="VKP0">
70.00
</price>
</prices>
<prices value="NLWS">
<price type="VKP0">
70.00
</price>
<price type="VKA0">
55.00
</price>
</prices>
<xsl:key name="myKey" match="ZE1KONDM" use="normalize-space(VKORG)" />
<xsl:for-each select="ZE1KONDM">
<xsl:choose>
<xsl:when test="KONDART='VKP0'">
<xsl:element name="prices">
<xsl:element name="price">
<xsl:value-of select="key('myKey', normalize-space(VKORG))/MENGE"/>
</xsl:element>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:for-each>
但是它不起作用,因为它只需要一把钥匙
有一些方法可以用xslt解决这个问题?可能有更好的方法,但请尝试以下方法:
(参见输出源)I.XSLT1.0解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kZByM" match="ZE1KONDM" use="VKORG"/>
<xsl:template match="/*">
<result>
<xsl:apply-templates select=
"*[generate-id() = generate-id(key('kZByM', VKORG)[1])]"/>
</result>
</xsl:template>
<xsl:template match="ZE1KONDM">
<prices value="{VKORG}">
<xsl:apply-templates select="key('kZByM', VKORG)" mode="inGroup"/>
</prices>
</xsl:template>
<xsl:template match="ZE1KONDM" mode="inGroup">
<price type="{KONDART}">
<xsl:value-of select="MENGE"/>
</price>
</xsl:template>
</xsl:stylesheet>
<ZE1MARAM>
<ZE1KONDM SEGMENT="1">
<VKORG>NL01</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NL01</KONDWERT>
<MENGE>70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE>70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKA0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE>33.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
</ZE1MARAM>
<result>
<prices value="NL01">
<price type="VKP0">70.00</price>
</prices>
<prices value="NLWS">
<price type="VKP0">70.00</price>
<price type="VKA0">33.00</price>
</prices>
</result>
下面是的一个经典应用:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kZByM" match="ZE1KONDM" use="VKORG"/>
<xsl:template match="/*">
<result>
<xsl:apply-templates select=
"*[generate-id() = generate-id(key('kZByM', VKORG)[1])]"/>
</result>
</xsl:template>
<xsl:template match="ZE1KONDM">
<prices value="{VKORG}">
<xsl:apply-templates select="key('kZByM', VKORG)" mode="inGroup"/>
</prices>
</xsl:template>
<xsl:template match="ZE1KONDM" mode="inGroup">
<price type="{KONDART}">
<xsl:value-of select="MENGE"/>
</price>
</xsl:template>
</xsl:stylesheet>
<ZE1MARAM>
<ZE1KONDM SEGMENT="1">
<VKORG>NL01</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NL01</KONDWERT>
<MENGE>70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE>70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKA0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE>33.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
</ZE1MARAM>
<result>
<prices value="NL01">
<price type="VKP0">70.00</price>
</prices>
<prices value="NLWS">
<price type="VKP0">70.00</price>
<price type="VKA0">33.00</price>
</prices>
</result>
在提供的XML文档上应用此转换时:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kZByM" match="ZE1KONDM" use="VKORG"/>
<xsl:template match="/*">
<result>
<xsl:apply-templates select=
"*[generate-id() = generate-id(key('kZByM', VKORG)[1])]"/>
</result>
</xsl:template>
<xsl:template match="ZE1KONDM">
<prices value="{VKORG}">
<xsl:apply-templates select="key('kZByM', VKORG)" mode="inGroup"/>
</prices>
</xsl:template>
<xsl:template match="ZE1KONDM" mode="inGroup">
<price type="{KONDART}">
<xsl:value-of select="MENGE"/>
</price>
</xsl:template>
</xsl:stylesheet>
<ZE1MARAM>
<ZE1KONDM SEGMENT="1">
<VKORG>NL01</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NL01</KONDWERT>
<MENGE>70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE>70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKA0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE>33.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
</ZE1MARAM>
<result>
<prices value="NL01">
<price type="VKP0">70.00</price>
</prices>
<prices value="NLWS">
<price type="VKP0">70.00</price>
<price type="VKA0">33.00</price>
</prices>
</result>
NL01
VKP0
99991231
20120605
NL01
70
欧元
NLWS
VKP0
99991231
20120605
NLWS
70
欧元
NLWS
VKA0
99991231
20120605
NLWS
33
欧元
生成所需的正确结果:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kZByM" match="ZE1KONDM" use="VKORG"/>
<xsl:template match="/*">
<result>
<xsl:apply-templates select=
"*[generate-id() = generate-id(key('kZByM', VKORG)[1])]"/>
</result>
</xsl:template>
<xsl:template match="ZE1KONDM">
<prices value="{VKORG}">
<xsl:apply-templates select="key('kZByM', VKORG)" mode="inGroup"/>
</prices>
</xsl:template>
<xsl:template match="ZE1KONDM" mode="inGroup">
<price type="{KONDART}">
<xsl:value-of select="MENGE"/>
</price>
</xsl:template>
</xsl:stylesheet>
<ZE1MARAM>
<ZE1KONDM SEGMENT="1">
<VKORG>NL01</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NL01</KONDWERT>
<MENGE>70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKP0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE>70.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
<ZE1KONDM SEGMENT="1">
<VKORG>NLWS</VKORG>
<KONDART>VKA0</KONDART>
<BEGINDATUM>99991231</BEGINDATUM>
<ENDDATUM>20120605</ENDDATUM>
<KONDWERT>NLWS</KONDWERT>
<MENGE>33.00</MENGE>
<CURRENCY>EUR</CURRENCY>
</ZE1KONDM>
</ZE1MARAM>
<result>
<prices value="NL01">
<price type="VKP0">70.00</price>
</prices>
<prices value="NLWS">
<price type="VKP0">70.00</price>
<price type="VKA0">33.00</price>
</prices>
</result>
70
70
33
请注意:Muenchian分组方法可能是最快的XSLT 1.0分组方法,因为它使用键。其他方法(例如比较同级值)的速度太慢(O(N^2)),这对于在大数据量上使用它们是禁止的
II。XSLT 2.0解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<result>
<xsl:for-each-group select="*" group-by="VKORG">
<prices value="{VKORG}">
<xsl:apply-templates select="current-group()"/>
</prices>
</xsl:for-each-group>
</result>
</xsl:template>
<xsl:template match="ZE1KONDM">
<price type="{KONDART}">
<xsl:value-of select="MENGE"/>
</price>
</xsl:template>
</xsl:stylesheet>
<result>
<prices value="NL01">
<price type="VKP0">70.00</price>
</prices>
<prices value="NLWS">
<price type="VKP0">70.00</price>
<price type="VKA0">33.00</price>
</prices>
</result>
将此转换应用于同一XML文档(如上)时,会产生相同的正确结果:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<result>
<xsl:for-each-group select="*" group-by="VKORG">
<prices value="{VKORG}">
<xsl:apply-templates select="current-group()"/>
</prices>
</xsl:for-each-group>
</result>
</xsl:template>
<xsl:template match="ZE1KONDM">
<price type="{KONDART}">
<xsl:value-of select="MENGE"/>
</price>
</xsl:template>
</xsl:stylesheet>
<result>
<prices value="NL01">
<price type="VKP0">70.00</price>
</prices>
<prices value="NLWS">
<price type="VKP0">70.00</price>
<price type="VKA0">33.00</price>
</prices>
</result>
70
70
33
说明:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<result>
<xsl:for-each-group select="*" group-by="VKORG">
<prices value="{VKORG}">
<xsl:apply-templates select="current-group()"/>
</prices>
</xsl:for-each-group>
</result>
</xsl:template>
<xsl:template match="ZE1KONDM">
<price type="{KONDART}">
<xsl:value-of select="MENGE"/>
</price>
</xsl:template>
</xsl:stylesheet>
<result>
<prices value="NL01">
<price type="VKP0">70.00</price>
</prices>
<prices value="NLWS">
<price type="VKP0">70.00</price>
<price type="VKA0">33.00</price>
</prices>
</result>
正确使用和group by
属性以及功能。如果我有类似的列表。。。。。。。。。。。。。。。那么它就不起作用了你有什么解决办法吗?