XSLT无法弄清楚如何正确分组

时间:2013-05-29 08:59:56

标签: xml xslt xslt-2.0 xslt-grouping muenchian-grouping

我有以下XML文件,该文件是从Oracle-DB导出的:http://pastebin.com/0yPcc7HT

我需要将其转换为以下结构:

<?xml version="1.0" encoding="UTF-8"?>
<ROWSET>
   <KUNDE>
      <KUNDENNR>59957</KUNDENNR>
      <ANSPRECHPARTNERS>
         <ANSPRECHPARTNER>
            <ANSPRECHNR>3</ANSPRECHNR>
            <FUNKTION>lfd. Kontakt,                 </FUNKTION>
            <VORNAME>Some                         </VORNAME>
            <NACHNAME>Dude                     </NACHNAME>
            <ABTEILUNG>Einkauf                       </ABTEILUNG>
            <EMAIL>Some.Dude@some.url.com</EMAIL>
            <TELEFON>123456789</TELEFON>
            <PREISLISTEN>
               <PREISLISTE>Katalog                       </PREISLISTE>
               <PREISLISTE>Y OO                          </PREISLISTE>
               <PREISLISTE>Kopierpapier "A"              </PREISLISTE>
               <PREISLISTE>Aktion Internet               </PREISLISTE>
               <PREISLISTE>Tinte Toner "H"               </PREISLISTE>
               <PREISLISTE>News Internet                 </PREISLISTE>
            </PREISLISTEN>
            <SPESEN>
               <SPESE>Sonderbeschaffungskosten      </SPESE> 
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
            </SPESEN>
         </ANSPRECHPARTNER>
         <ANSPRECHPARTNER>
            <ANSPRECHNR>1</ANSPRECHNR>
            <FUNKTION>Sachbearbeitung               </FUNKTION>
            <VORNAME>Another                      </VORNAME>
            <NACHNAME>Dudarina                    </NACHNAME>
            <ABTEILUNG>Einkauf                       </ABTEILUNG>
            <EMAIL>Another.Dudarina@some.url.com</EMAIL>
            <TELEFON>+43 17007 32102</TELEFON>
            <PREISLISTEN>
               <PREISLISTE>Katalog                       </PREISLISTE>
               <PREISLISTE>Y OO                          </PREISLISTE>
               <PREISLISTE>Kopierpapier "A"              </PREISLISTE>
               <PREISLISTE>Aktion Internet               </PREISLISTE>
               <PREISLISTE>Tinte Toner "H"               </PREISLISTE>
               <PREISLISTE>News Internet                 </PREISLISTE>
            </PREISLISTEN>
            <SPESEN>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
            </SPESEN>
         </ANSPRECHPARTNER>
      </ANSPRECHPARTNERS>
   </KUNDE>
</ROWSET>

我已经尝试了很多小时不同的事情,但我无法找到如何正确地做到这一点。这就是我的XSLT文件的样子:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:key name="rowsByKDNR" match="ROW" use="concat(KUNDENNR, '+', ANSPRECHNR)"></xsl:key>

    <xsl:template match="ROWSET">

        <ROWSET>
            <xsl:for-each-group select="ROW" group-by="KUNDENNR">
                <KUNDE>
                    <xsl:copy-of select="KUNDENNR" />
                    <ANSPRECHPARTNERS>
                        <xsl:for-each select="current-group()[count(. | key('rowsByMonth', concat(KUNDENNR, '+', ANSPRECHNR))[1]) = 1]">
                            <ANSPRECHPARTNER>
                                <xsl:copy-of select="ANSPRECHNR" />
                                <xsl:copy-of select="FUNKTION" />
                                <xsl:copy-of select="VORNAME" />
                                <xsl:copy-of select="NACHNAME" />
                                <xsl:copy-of select="ABTEILUNG" />
                                <xsl:copy-of select="EMAIL" />
                                <xsl:copy-of select="TELEFON" />
                                <PREISLISTEN>
                                    <xsl:for-each select="key('rowsByKDNR', concat(KUNDENNR, '+', ANSPRECHNR))">
                                            <xsl:copy-of select="PREISLISTE" />
                                    </xsl:for-each>
                                </PREISLISTEN>
                                <SPESEN>
                                    <xsl:for-each select="key('rowsByKDNR', concat(KUNDENNR, '+', ANSPRECHNR))">
                                        <SPESE>
                                            <xsl:value-of select="SPESEN" />
                                        </SPESE>
                                    </xsl:for-each>
                                </SPESEN>
                            </ANSPRECHPARTNER>
                        </xsl:for-each>
                    </ANSPRECHPARTNERS>
                </KUNDE>
            </xsl:for-each-group>

        </ROWSET>
    </xsl:template></xsl:stylesheet>

但这给了我以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<ROWSET>
   <KUNDE>
      <KUNDENNR>59957</KUNDENNR>
      <ANSPRECHPARTNERS>
         <ANSPRECHPARTNER>
            <ANSPRECHNR>3</ANSPRECHNR>
            <FUNKTION>lfd. Kontakt,                 </FUNKTION>
            <VORNAME>Some                         </VORNAME>
            <NACHNAME>Dude                     </NACHNAME>
            <ABTEILUNG>Einkauf                       </ABTEILUNG>
            <EMAIL>Some.Dude@some.url.com</EMAIL>
            <TELEFON>123456789</TELEFON>
            <PREISLISTEN>
               <PREISLISTE>Katalog                       </PREISLISTE>
               <PREISLISTE>Y OO                          </PREISLISTE>
               <PREISLISTE>Kopierpapier "A"              </PREISLISTE>
               <PREISLISTE>Aktion Internet               </PREISLISTE>
               <PREISLISTE>Tinte Toner "H"               </PREISLISTE>
               <PREISLISTE>News Internet                 </PREISLISTE>
               <PREISLISTE>Katalog                       </PREISLISTE>
               <PREISLISTE>Y OO                          </PREISLISTE>
               <PREISLISTE>Kopierpapier "A"              </PREISLISTE>
               <PREISLISTE>Aktion Internet               </PREISLISTE>
               <PREISLISTE>Tinte Toner "H"               </PREISLISTE>
               <PREISLISTE>News Internet                 </PREISLISTE>
            </PREISLISTEN>
            <SPESEN>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
            </SPESEN>
         </ANSPRECHPARTNER>
         <ANSPRECHPARTNER>
            <ANSPRECHNR>1</ANSPRECHNR>
            <FUNKTION>Sachbearbeitung               </FUNKTION>
            <VORNAME>Another                      </VORNAME>
            <NACHNAME>Dudarina                    </NACHNAME>
            <ABTEILUNG>Einkauf                       </ABTEILUNG>
            <EMAIL>Another.Dudarina@some.url.com</EMAIL>
            <TELEFON>+43 17007 32102</TELEFON>
            <PREISLISTEN>
               <PREISLISTE>Katalog                       </PREISLISTE>
               <PREISLISTE>Y OO                          </PREISLISTE>
               <PREISLISTE>Kopierpapier "A"              </PREISLISTE>
               <PREISLISTE>Aktion Internet               </PREISLISTE>
               <PREISLISTE>Tinte Toner "H"               </PREISLISTE>
               <PREISLISTE>News Internet                 </PREISLISTE>
               <PREISLISTE>Katalog                       </PREISLISTE>
               <PREISLISTE>Y OO                          </PREISLISTE>
               <PREISLISTE>Kopierpapier "A"              </PREISLISTE>
               <PREISLISTE>Aktion Internet               </PREISLISTE>
               <PREISLISTE>Tinte Toner "H"               </PREISLISTE>
               <PREISLISTE>News Internet                 </PREISLISTE>
            </PREISLISTEN>
            <SPESEN>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
            </SPESEN>
         </ANSPRECHPARTNER>
      </ANSPRECHPARTNERS>
   </KUNDE>
</ROWSET>

PREISLISTENSPESEN中的元素过于频繁。我做错了什么,为了让它发挥作用我需要改变什么?

提前谢谢

1 个答案:

答案 0 :(得分:1)

首先,假设您可以使用XSLT 2.0处理器和for-each-group,我不会打扰键和Muenchian分组,我只需要根据需要嵌套for-each-group指令。

基于此,当Saxon 9.5应用样式表

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes" />

  <xsl:template match="ROWSET">

    <ROWSET>
      <xsl:for-each-group select="ROW" group-by="KUNDENNR">
        <KUNDE>
          <xsl:copy-of select="KUNDENNR" />
          <ANSPRECHPARTNERS>
            <xsl:for-each-group select="current-group()" group-by="ANSPRECHNR">
              <ANSPRECHPARTNER>
                <xsl:copy-of select="ANSPRECHNR, FUNKTION, VORNAME, NACHNAME,
                                                    ABTEILUNG, EMAIL, TELEFON" />
                <PREISLISTEN>
                  <xsl:for-each-group select="current-group()" group-by="PREISLISTE">
                    <xsl:copy-of select="PREISLISTE"/>
                  </xsl:for-each-group>
                </PREISLISTEN>
                <SPESEN>
                  <xsl:for-each-group select="current-group()" group-by="SPESEN">
                    <SPESE>
                      <xsl:value-of select="current-grouping-key()" />
                    </SPESE>
                  </xsl:for-each-group>
                </SPESEN>
              </ANSPRECHPARTNER>
            </xsl:for-each-group>
          </ANSPRECHPARTNERS>
        </KUNDE>
      </xsl:for-each-group>

    </ROWSET>
  </xsl:template>

</xsl:stylesheet>

到您链接到它的输入会创建以下结果

<?xml version="1.0" encoding="UTF-8"?>
<ROWSET>
   <KUNDE>
      <KUNDENNR>59957</KUNDENNR>
      <ANSPRECHPARTNERS>
         <ANSPRECHPARTNER>
            <ANSPRECHNR>3</ANSPRECHNR>
            <FUNKTION>lfd. Kontakt,                 </FUNKTION>
            <VORNAME>Some                         </VORNAME>
            <NACHNAME>Dude                     </NACHNAME>
            <ABTEILUNG>Einkauf                       </ABTEILUNG>
            <EMAIL>Some.Dude@some.url.com</EMAIL>
            <TELEFON>123456789</TELEFON>
            <PREISLISTEN>
               <PREISLISTE>Katalog                       </PREISLISTE>
               <PREISLISTE>Y OO                          </PREISLISTE>
               <PREISLISTE>Kopierpapier "A"              </PREISLISTE>
               <PREISLISTE>Aktion Internet               </PREISLISTE>
               <PREISLISTE>Tinte Toner "H"               </PREISLISTE>
               <PREISLISTE>News Internet                 </PREISLISTE>
            </PREISLISTEN>
            <SPESEN>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
            </SPESEN>
         </ANSPRECHPARTNER>
         <ANSPRECHPARTNER>
            <ANSPRECHNR>1</ANSPRECHNR>
            <FUNKTION>Sachbearbeitung               </FUNKTION>
            <VORNAME>Another                      </VORNAME>
            <NACHNAME>Dudarina                    </NACHNAME>
            <ABTEILUNG>Einkauf                       </ABTEILUNG>
            <EMAIL>Another.Dudarina@some.url.com</EMAIL>
            <TELEFON>+43 17007 32102</TELEFON>
            <PREISLISTEN>
               <PREISLISTE>Katalog                       </PREISLISTE>
               <PREISLISTE>Y OO                          </PREISLISTE>
               <PREISLISTE>Kopierpapier "A"              </PREISLISTE>
               <PREISLISTE>Aktion Internet               </PREISLISTE>
               <PREISLISTE>Tinte Toner "H"               </PREISLISTE>
               <PREISLISTE>News Internet                 </PREISLISTE>
            </PREISLISTEN>
            <SPESEN>
               <SPESE>Sonderbeschaffungskosten      </SPESE>
               <SPESE>MM-Zuschlag55 3.6             </SPESE>
            </SPESEN>
         </ANSPRECHPARTNER>
      </ANSPRECHPARTNERS>
   </KUNDE>
</ROWSET>