1

同じ型のデータをすべて 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>

そのため、結果の 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>

しかし、キーが1つしかないため機能しません..

xslt でこの問題を解決する方法はありますか?

4

2 に答える 2

1

I. XSLT 1.0ソリューション:

Muenchianグループ化方法の古典的なアプリケーションは次のとおりです。

<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>

この変換が提供された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>

必要な正しい結果が生成されます。

<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>

: Muenchianグループ化方法は、キーを使用するため、おそらく最速のXSLT1.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>

この変換が同じXMLドキュメント(上記)に適用されると、同じ正しい結果が生成されます。

<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:for-each-groupの適切な使用。group-bycurrent-group()

于 2012-06-12T12:30:41.367 に答える
1

おそらくもっと良い方法がありますが、これを試してください:

http://www.xmlplayground.com/2A3C7H

(出力ソースを参照)

于 2012-06-12T09:03:27.567 に答える