使用XSLT连接相同类型的数据

使用XSLT连接相同类型的数据,xslt,Xslt,我想用XSLT连接相同类型的所有数据。我有以下XML: <ZE1MARAM> <ZE1KONDM SEGMENT="1"> <VKORG>NL01</VKORG> <KONDART>VKP0</KONDART> <BEGINDATUM>99991231</BEGINDATUM> <EN

我想用XSLT连接相同类型的所有数据。我有以下XML:

<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
属性以及功能。

如果我有类似的列表。。。。。。。。。。。。。。。那么它就不起作用了你有什么解决办法吗?