bogdan
bogdan

Reputation: 27

xslt grouping issue

i have a problem with grouping using XSLT. Here is my example : This is the input file:

 <HeadNr>
  <nummerK>989</nummerK>
  </HeadNr>

     <Qua>
      <Abrufd>921</Abrufd>
      <Abrufm>20</Abrufm>
      <Summe>103,1</Summe>
      <Einzel>42,1</Einzel>
    </Qua>

    <HeadNr>
  <nummerK>911</nummerK>
  </HeadNr>

     <Qua>
      <Abrufd>321</Abrufd>
      <Abrufm>40</Abrufm>
      <Summe>143,1</Summe>
      <Einzel>222,1</Einzel>
    </Qua>

    <HeadNr>
  <nummerK>989</nummerK>
  </HeadNr>

     <Qua>
      <Abrufd>922</Abrufd>
      <Abrufm>204</Abrufm>
      <Summe>1033,1</Summe>
      <Einzel>4222,1</Einzel>
    </Qua>

This is the output file:

<root>
<HeadNr>
  <nummerK>989</nummerK>
  </HeadNr>

     <Qua>
      <Abrufd>921</Abrufd>
      <Abrufm>20</Abrufm>
      <Summe>103,1</Summe>
      <Einzel>42,1</Einzel>
    </Qua>
 </root>
 <root>   
    <HeadNr>
  <nummerK>911</nummerK>
  </HeadNr>

     <Qua>
      <Abrufd>321</Abrufd>
      <Abrufm>40</Abrufm>
      <Summe>143,1</Summe>
      <Einzel>222,1</Einzel>
    </Qua>
 </root>
 <root>   
    <HeadNr>
  <nummerK>989</nummerK>
  </HeadNr>

     <Qua>
      <Abrufd>922</Abrufd>
      <Abrufm>204</Abrufm>
      <Summe>1033,1</Summe>
      <Einzel>4222,1</Einzel>
    </Qua>
</root>

I need to put the tags and and everything between them in an tag. Thank you and sorry for my English.

Upvotes: 2

Views: 61

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

This transformation:

<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:template match="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="HeadNr">
  <root>
   <HeadNr>
     <xsl:apply-templates/>
   </HeadNr>
   <xsl:apply-templates select="following-sibling::Qua[1]" mode="inGroup"/>
  </root>
 </xsl:template>

 <xsl:template match="Qua" mode="inGroup"><xsl:call-template name="identity"/></xsl:template>
 <xsl:template match="Qua"/>
</xsl:stylesheet>

when applied on this XML document (the provided fragment wrapped into a single top element):

<t>
    <HeadNr>
        <nummerK>989</nummerK>
    </HeadNr>
    <Qua>
        <Abrufd>921</Abrufd>
        <Abrufm>20</Abrufm>
        <Summe>103,1</Summe>
        <Einzel>42,1</Einzel>
    </Qua>
    <HeadNr>
        <nummerK>911</nummerK>
    </HeadNr>
    <Qua>
        <Abrufd>321</Abrufd>
        <Abrufm>40</Abrufm>
        <Summe>143,1</Summe>
        <Einzel>222,1</Einzel>
    </Qua>
    <HeadNr>
        <nummerK>989</nummerK>
    </HeadNr>
    <Qua>
        <Abrufd>922</Abrufd>
        <Abrufm>204</Abrufm>
        <Summe>1033,1</Summe>
        <Einzel>4222,1</Einzel>
    </Qua>
</t>

produces the wanted, correct result:

<t>
   <root>
      <HeadNr>
         <nummerK>989</nummerK>
      </HeadNr>
      <Qua>
         <Abrufd>921</Abrufd>
         <Abrufm>20</Abrufm>
         <Summe>103,1</Summe>
         <Einzel>42,1</Einzel>
      </Qua>
   </root>
   <root>
      <HeadNr>
         <nummerK>911</nummerK>
      </HeadNr>
      <Qua>
         <Abrufd>321</Abrufd>
         <Abrufm>40</Abrufm>
         <Summe>143,1</Summe>
         <Einzel>222,1</Einzel>
      </Qua>
   </root>
   <root>
      <HeadNr>
         <nummerK>989</nummerK>
      </HeadNr>
      <Qua>
         <Abrufd>922</Abrufd>
         <Abrufm>204</Abrufm>
         <Summe>1033,1</Summe>
         <Einzel>4222,1</Einzel>
      </Qua>
   </root>
</t>

Do note:

This transformation looks longer than a solution which simply uses <xsl:copy-of>. However, it is more flexoble and expandable, allowing additional templates to be defined that match the elements inside the groups.

Upvotes: 1

Tim C
Tim C

Reputation: 70598

It looks like you are trying to 'group' the HeadNr elements with the first following Qua sibling.

Assuming your input XML had a root element to your XML, you would start by simply selecting the HeadNr elements

<xsl:apply-templates select="HeadNr" />

Then you would have a template to match these, were you create the root element, and copy the current element, and the following Qua element.

Here is the full XSLT

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

   <xsl:template match="/*">
      <xsl:apply-templates select="HeadNr" />
   </xsl:template>

   <xsl:template match="HeadNr">
      <root>
         <xsl:copy-of select="." />
         <xsl:copy-of select="following-sibling::Qua[1]" />
      </root>
   </xsl:template>
</xsl:stylesheet>

When applied to your XML (when given a root element), then the following is output

<root>
    <HeadNr>
        <nummerK>989</nummerK>
    </HeadNr>
    <Qua>
        <Abrufd>921</Abrufd>
        <Abrufm>20</Abrufm>
        <Summe>103,1</Summe>
        <Einzel>42,1</Einzel>
    </Qua>
</root>
<root>
    <HeadNr>
        <nummerK>911</nummerK>
    </HeadNr>
    <Qua>
        <Abrufd>321</Abrufd>
        <Abrufm>40</Abrufm>
        <Summe>143,1</Summe>
        <Einzel>222,1</Einzel>
    </Qua>
</root>
<root>
    <HeadNr>
        <nummerK>989</nummerK>
    </HeadNr>
    <Qua>
        <Abrufd>922</Abrufd>
        <Abrufm>204</Abrufm>
        <Summe>1033,1</Summe>
        <Einzel>4222,1</Einzel>
    </Qua>
</root>

Upvotes: 1

Related Questions