Help on xslt - grouping

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Per Jørgen Vigdal

    Help on xslt - grouping

    I have a XML that I need to map.
    The XML goes like:

    <Children>
    <Child>
    <References>
    <External>
    <Reference name="filename" value="1.dat"/>
    <Reference name="invoicenr " value="1111111"/>
    <Reference name="invoicer_ name" value="Bill"/>
    <Reference name="invoicere f" value="bbbbbb"/>
    </External>
    </References>
    </Child>
    <Child>
    <References>
    <External>
    <Reference name="filename" value="2.dat"/>
    <Reference name="invoicenr " value="222222"/>
    <Reference name="invoicer_ name" value="Bill"/>
    <Reference name="invoicere f" value="bbbbbb"/>
    </External>
    </References>
    </Child>
    <Child>
    <References>
    <External>
    <Reference name="filename" value="3.dat"/>
    <Reference name="invoicenr " value="33333"/>
    <Reference name="invoicer_ name" value="Clinton"/>
    <Reference name="invoicere f" value="ccccc"/>
    </External>
    </References>
    </Child>
    </Children>

    I want the structure to map to:

    <Senders>
    <Sender>
    <invoicer_name> Bill</invoicer_name>
    <invoiceref>bbb bbb</invoiceref>
    <Items TotalItems="2"/>
    </Sender>
    <Sender>
    <invoicer_name> Clinton</invoicer_name>
    <invoiceref>ccc cc</invoiceref>
    <Items TotalItems="1"/>
    </Sender>
    </Senders>

    I have tried to use the "Muenchian Grouping" method, but am not able to
    obtain both
    <invoicer_nam e> and <invoiceref> under the <Sender> tag

    Here is my xsl :

    <xsl:styleshe et version="1.0"
    xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:output encoding="ISO-8859-1"/>
    <xsl:key name="kDistinct Sender"
    match="Children/Child/References/External/Reference[@name='invoicer _name']/@
    value" use="."/>
    <xsl:template match="/">
    <Senders>
    <!-- go through distinct InvoicerName -->
    <xsl:for-each
    select="/Children/Child/References/External/Reference[@name='invoicer _name']
    /@value[generate-id()=generate-id(key('kDistin ctSender',.))]">
    <!-- sort by InvoicerName -->
    <xsl:sort select="."/>
    <Sender>
    <xsl:variable name="InvoicerN ame">
    <xsl:value-of select="."/>
    </xsl:variable>
    <InvoicerName >
    <xsl:value-of select="$Invoic erName"/>
    </InvoicerName>
    <Items TotalItems="{co unt(key('kDisti nctSender',.))} ">
    </Items>
    </Sender>
    </xsl:for-each>
    </Senders>
    </xsl:template>
    </xsl:stylesheet>


  • Dimitre Novatchev

    #2
    Re: Help on xslt - grouping

    Specify for the "use" attribute of xsl:key the concatenation of the values
    of "invoicer_n ame" and "invoiceref ".


    Cheers,
    Dimitre Novatchev


    "Per Jørgen Vigdal" <per.jorgen.vig dal@ergo.no> wrote in message
    news:1116520924 .104290@makrell .interpost.no.. .[color=blue]
    >I have a XML that I need to map.
    > The XML goes like:
    >
    > <Children>
    > <Child>
    > <References>
    > <External>
    > <Reference name="filename" value="1.dat"/>
    > <Reference name="invoicenr " value="1111111"/>
    > <Reference name="invoicer_ name" value="Bill"/>
    > <Reference name="invoicere f" value="bbbbbb"/>
    > </External>
    > </References>
    > </Child>
    > <Child>
    > <References>
    > <External>
    > <Reference name="filename" value="2.dat"/>
    > <Reference name="invoicenr " value="222222"/>
    > <Reference name="invoicer_ name" value="Bill"/>
    > <Reference name="invoicere f" value="bbbbbb"/>
    > </External>
    > </References>
    > </Child>
    > <Child>
    > <References>
    > <External>
    > <Reference name="filename" value="3.dat"/>
    > <Reference name="invoicenr " value="33333"/>
    > <Reference name="invoicer_ name" value="Clinton"/>
    > <Reference name="invoicere f" value="ccccc"/>
    > </External>
    > </References>
    > </Child>
    > </Children>
    >
    > I want the structure to map to:
    >
    > <Senders>
    > <Sender>
    > <invoicer_name> Bill</invoicer_name>
    > <invoiceref>bbb bbb</invoiceref>
    > <Items TotalItems="2"/>
    > </Sender>
    > <Sender>
    > <invoicer_name> Clinton</invoicer_name>
    > <invoiceref>ccc cc</invoiceref>
    > <Items TotalItems="1"/>
    > </Sender>
    > </Senders>
    >
    > I have tried to use the "Muenchian Grouping" method, but am not able to
    > obtain both
    > <invoicer_nam e> and <invoiceref> under the <Sender> tag
    >
    > Here is my xsl :
    >
    > <xsl:styleshe et version="1.0"
    > xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
    > <xsl:output method="xml" indent="yes"/>
    > <xsl:output encoding="ISO-8859-1"/>
    > <xsl:key name="kDistinct Sender"
    > match="Children/Child/References/External/Reference[@name='invoicer _name']/@
    > value" use="."/>
    > <xsl:template match="/">
    > <Senders>
    > <!-- go through distinct InvoicerName -->
    > <xsl:for-each
    > select="/Children/Child/References/External/Reference[@name='invoicer _name']
    > /@value[generate-id()=generate-id(key('kDistin ctSender',.))]">
    > <!-- sort by InvoicerName -->
    > <xsl:sort select="."/>
    > <Sender>
    > <xsl:variable name="InvoicerN ame">
    > <xsl:value-of select="."/>
    > </xsl:variable>
    > <InvoicerName >
    > <xsl:value-of select="$Invoic erName"/>
    > </InvoicerName>
    > <Items TotalItems="{co unt(key('kDisti nctSender',.))} ">
    > </Items>
    > </Sender>
    > </xsl:for-each>
    > </Senders>
    > </xsl:template>
    > </xsl:stylesheet>
    >
    >[/color]


    Comment

    • Per Jørgen Vigdal

      #3
      Re: Help on xslt - grouping

      Thanks
      I have tried to play around with concatenation and cant get it right, her is
      the result :

      <Senders>
      <Sender>
      <InvoicerName>B ill</InvoicerName>
      <Items TotalItems="3"/>
      </Sender>
      </Senders>


      Using xsl :

      <xsl:styleshe et version="1.0"
      xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
      <xsl:output encoding="ISO-8859-1"/>
      <xsl:key name="kDistinct Sender"
      match="Children/Child/References/External/Reference[@name='invoicer _name']/@
      value" use="concat(@na me,'||',@value) "/>
      <xsl:template match="/">
      <Senders>

      <xsl:for-each
      select="/Children/Child/References/External/Reference[@name='invoicer _name']
      /@value[generate-id()=generate-id(key('kDistin ctSender',conca t(@name,'||',@v
      alue)))]">

      <xsl:sort select="."/>
      <Sender>
      <xsl:variable name="InvoicerN ame">
      <xsl:value-of select="."/>
      </xsl:variable>
      <InvoicerName >
      <xsl:value-of select="$Invoic erName"/>
      </InvoicerName>
      <Items
      TotalItems="{co unt(key('kDisti nctSender',conc at(@name,'||',@ value)))}">
      </Items>
      </Sender>
      </xsl:for-each>
      </Senders>
      </xsl:template>
      </xsl:stylesheet>
      "Dimitre Novatchev" <dimitren@tpg.c om.au> wrote in message
      news:428cf388$0 $73807$892e7fe2 @authen.white.r eadfreenews.net ...[color=blue]
      > Specify for the "use" attribute of xsl:key the concatenation of the values
      > of "invoicer_n ame" and "invoiceref ".
      >
      >
      > Cheers,
      > Dimitre Novatchev
      >
      >
      > "Per Jørgen Vigdal" <per.jorgen.vig dal@ergo.no> wrote in message
      > news:1116520924 .104290@makrell .interpost.no.. .[color=green]
      > >I have a XML that I need to map.
      > > The XML goes like:
      > >
      > > <Children>
      > > <Child>
      > > <References>
      > > <External>
      > > <Reference name="filename" value="1.dat"/>
      > > <Reference name="invoicenr " value="1111111"/>
      > > <Reference name="invoicer_ name" value="Bill"/>
      > > <Reference name="invoicere f" value="bbbbbb"/>
      > > </External>
      > > </References>
      > > </Child>
      > > <Child>
      > > <References>
      > > <External>
      > > <Reference name="filename" value="2.dat"/>
      > > <Reference name="invoicenr " value="222222"/>
      > > <Reference name="invoicer_ name" value="Bill"/>
      > > <Reference name="invoicere f" value="bbbbbb"/>
      > > </External>
      > > </References>
      > > </Child>
      > > <Child>
      > > <References>
      > > <External>
      > > <Reference name="filename" value="3.dat"/>
      > > <Reference name="invoicenr " value="33333"/>
      > > <Reference name="invoicer_ name" value="Clinton"/>
      > > <Reference name="invoicere f" value="ccccc"/>
      > > </External>
      > > </References>
      > > </Child>
      > > </Children>
      > >
      > > I want the structure to map to:
      > >
      > > <Senders>
      > > <Sender>
      > > <invoicer_name> Bill</invoicer_name>
      > > <invoiceref>bbb bbb</invoiceref>
      > > <Items TotalItems="2"/>
      > > </Sender>
      > > <Sender>
      > > <invoicer_name> Clinton</invoicer_name>
      > > <invoiceref>ccc cc</invoiceref>
      > > <Items TotalItems="1"/>
      > > </Sender>
      > > </Senders>
      > >
      > > I have tried to use the "Muenchian Grouping" method, but am not able to
      > > obtain both
      > > <invoicer_nam e> and <invoiceref> under the <Sender> tag
      > >
      > > Here is my xsl :
      > >
      > > <xsl:styleshe et version="1.0"
      > > xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
      > > <xsl:output method="xml" indent="yes"/>
      > > <xsl:output encoding="ISO-8859-1"/>
      > > <xsl:key name="kDistinct Sender"
      > >[/color][/color]
      match="Children/Child/References/External/Reference[@name='invoicer _name']/@[color=blue][color=green]
      > > value" use="."/>
      > > <xsl:template match="/">
      > > <Senders>
      > > <!-- go through distinct InvoicerName -->
      > > <xsl:for-each
      > >[/color][/color]
      select="/Children/Child/References/External/Reference[@name='invoicer _name'][color=blue][color=green]
      > > /@value[generate-id()=generate-id(key('kDistin ctSender',.))]">
      > > <!-- sort by InvoicerName -->
      > > <xsl:sort select="."/>
      > > <Sender>
      > > <xsl:variable name="InvoicerN ame">
      > > <xsl:value-of select="."/>
      > > </xsl:variable>
      > > <InvoicerName >
      > > <xsl:value-of select="$Invoic erName"/>
      > > </InvoicerName>
      > > <Items TotalItems="{co unt(key('kDisti nctSender',.))} ">
      > > </Items>
      > > </Sender>
      > > </xsl:for-each>
      > > </Senders>
      > > </xsl:template>
      > > </xsl:stylesheet>
      > >
      > >[/color]
      >
      >[/color]


      Comment

      • Volkm@r

        #4
        Re: Help on xslt - grouping

        Per Jørgen Vigdal wrote:[color=blue]
        > I have a XML that I need to map.
        > The XML goes like:
        >
        > <Children>
        > <Child>
        > <References>
        > <External>
        > <Reference name="filename" value="1.dat"/>
        > <Reference name="invoicenr " value="1111111"/>
        > <Reference name="invoicer_ name" value="Bill"/>
        > <Reference name="invoicere f" value="bbbbbb"/>
        > </External>
        > </References>
        > </Child>
        > <Child>
        > <References>
        > <External>
        > <Reference name="filename" value="2.dat"/>
        > <Reference name="invoicenr " value="222222"/>
        > <Reference name="invoicer_ name" value="Bill"/>
        > <Reference name="invoicere f" value="bbbbbb"/>
        > </External>
        > </References>
        > </Child>
        > <Child>
        > <References>
        > <External>
        > <Reference name="filename" value="3.dat"/>
        > <Reference name="invoicenr " value="33333"/>
        > <Reference name="invoicer_ name" value="Clinton"/>
        > <Reference name="invoicere f" value="ccccc"/>
        > </External>
        > </References>
        > </Child>
        > </Children>
        >
        > I want the structure to map to:
        >
        > <Senders>
        > <Sender>
        > <invoicer_name> Bill</invoicer_name>
        > <invoiceref>bbb bbb</invoiceref>
        > <Items TotalItems="2"/>
        > </Sender>
        > <Sender>
        > <invoicer_name> Clinton</invoicer_name>
        > <invoiceref>ccc cc</invoiceref>
        > <Items TotalItems="1"/>
        > </Sender>
        > </Senders>
        >
        > I have tried to use the "Muenchian Grouping" method, but am not able to
        > obtain both
        > <invoicer_nam e> and <invoiceref> under the <Sender> tag
        >
        > Here is my xsl :
        >
        > <xsl:styleshe et version="1.0"
        > xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
        > <xsl:output method="xml" indent="yes"/>
        > <xsl:output encoding="ISO-8859-1"/>
        > <xsl:key name="kDistinct Sender"
        > match="Children/Child/References/External/Reference[@name='invoicer _name']/@
        > value" use="."/>
        > <xsl:template match="/">
        > <Senders>
        > <!-- go through distinct InvoicerName -->
        > <xsl:for-each
        > select="/Children/Child/References/External/Reference[@name='invoicer _name']
        > /@value[generate-id()=generate-id(key('kDistin ctSender',.))]">
        > <!-- sort by InvoicerName -->
        > <xsl:sort select="."/>
        > <Sender>
        > <xsl:variable name="InvoicerN ame">
        > <xsl:value-of select="."/>
        > </xsl:variable>
        > <InvoicerName >
        > <xsl:value-of select="$Invoic erName"/>
        > </InvoicerName>
        > <Items TotalItems="{co unt(key('kDisti nctSender',.))} ">
        > </Items>
        > </Sender>
        > </xsl:for-each>
        > </Senders>
        > </xsl:template>
        > </xsl:stylesheet>
        >
        >[/color]

        Did you try to simply put them in the right order?


        <xsl:template match="/">
        <Senders>
        <!-- go through distinct InvoicerName -->
        <xsl:apply-templates select="-XPath expression-">
        </Senders>
        </xsl:template>

        <xsl:template match="-expression from above-">
        <Sender>
        <xsl:apply-templates select=".[@name='invoicer _name']"/>
        <xsl:apply-templates select=".[@name='invoicer ef']"/>
        <xsl:apply-templates select=".[@name='otherArt ributeName']"/>
        <xsl:apply-templates select=".[@name='........ ....']"/>
        <xsl:apply-templates select=".[@name='-one more line-']"/>
        </Sender>
        </xsl:apply-templates>
        </xsl:template>

        <xsl:.......... . - And Some More Templates - ........./>

        Comment

        • Dimitre Novatchev

          #5
          Re: Help on xslt - grouping


          "Per Jørgen Vigdal" <per.jorgen.vig dal@ergo.no> wrote in message
          news:1116535669 .557231@makrell .interpost.no.. .[color=blue]
          > Thanks
          > I have tried to play around with concatenation and cant get it right, her
          > is
          > the result :
          >
          > <Senders>
          > <Sender>
          > <InvoicerName>B ill</InvoicerName>
          > <Items TotalItems="3"/>
          > </Sender>
          > </Senders>[/color]


          This transformation:

          <xsl:styleshe et version="1.0"
          xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
          <xsl:output omit-xml-declaration="ye s" indent="yes"/>

          <xsl:strip-space elements="*"/>

          <xsl:key name="kExtNameR ef" match="External "
          use="concat(Ref erence[@name='invoicer _name']/@value,
          '+',
          Reference[@name='invoicer ef']/@value
          )"/>
          <xsl:template match="/">
          <Senders>
          <xsl:for-each select=
          "/*/*/*/External
          [generate-id()
          =
          generate-id(
          key('kExtNameRe f',
          concat(Referenc e[@name='invoicer _name']/@value,
          '+',
          Reference[@name='invoicer ef']/@value
          )
          )[1]
          )
          ]">
          <Sender>
          <invoicer_nam e>
          <xsl:value-of select=
          "Reference[@name='invoicer _name']/@value"/>
          </invoicer_name>
          <invoiceref>
          <xsl:value-of select=
          "Reference[@name='invoicer ef']/@value"/>
          </invoiceref>
          <Items TotalItems="{
          count(
          key('kExtNameRe f',
          concat(Referenc e[@name='invoicer _name']/@value,
          '+',
          Reference[@name='invoicer ef']/@value
          )
          )
          )
          }"/>
          </Sender>
          </xsl:for-each>
          </Senders>

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

          when applied on your source.xml:

          <Children>
          <Child>
          <References>
          <External>
          <Reference name="filename" value="1.dat"/>
          <Reference name="invoicenr " value="1111111"/>
          <Reference name="invoicer_ name" value="Bill"/>
          <Reference name="invoicere f" value="bbbbbb"/>
          </External>
          </References>
          </Child>
          <Child>
          <References>
          <External>
          <Reference name="filename" value="2.dat"/>
          <Reference name="invoicenr " value="222222"/>
          <Reference name="invoicer_ name" value="Bill"/>
          <Reference name="invoicere f" value="bbbbbb"/>
          </External>
          </References>
          </Child>
          <Child>
          <References>
          <External>
          <Reference name="filename" value="3.dat"/>
          <Reference name="invoicenr " value="33333"/>
          <Reference name="invoicer_ name" value="Clinton"/>
          <Reference name="invoicere f" value="ccccc"/>
          </External>
          </References>
          </Child>
          </Children>

          produces the wanted result:

          <Senders>
          <Sender>
          <invoicer_name> Bill</invoicer_name>
          <invoiceref>bbb bbb</invoiceref>
          <Items TotalItems="2" />
          </Sender>
          <Sender>
          <invoicer_name> Clinton</invoicer_name>
          <invoiceref>ccc cc</invoiceref>
          <Items TotalItems="1" />
          </Sender>
          </Senders>


          Hope this helped.

          Cheers,
          Dimitre Novatchev


          Comment

          • Per Jørgen Vigdal

            #6
            Re: Help on xslt - grouping

            This is great, exactly what I want. Thank you.
            This is goanna be tested in QA 22. Mai and if successful, put into
            production on 25. Mai where the
            xsl will do transformation on files that are as big as 100MB with thousands
            of items






            "Dimitre Novatchev" <dimitren@tpg.c om.au> wrote in message
            news:428db6ed$0 $75094$892e7fe2 @authen.white.r eadfreenews.net ...[color=blue]
            >
            > "Per Jørgen Vigdal" <per.jorgen.vig dal@ergo.no> wrote in message
            > news:1116535669 .557231@makrell .interpost.no.. .[color=green]
            > > Thanks
            > > I have tried to play around with concatenation and cant get it right,[/color][/color]
            her[color=blue][color=green]
            > > is
            > > the result :
            > >
            > > <Senders>
            > > <Sender>
            > > <InvoicerName>B ill</InvoicerName>
            > > <Items TotalItems="3"/>
            > > </Sender>
            > > </Senders>[/color]
            >
            >
            > This transformation:
            >
            > <xsl:styleshe et version="1.0"
            > xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
            > <xsl:output omit-xml-declaration="ye s" indent="yes"/>
            >
            > <xsl:strip-space elements="*"/>
            >
            > <xsl:key name="kExtNameR ef" match="External "
            > use="concat(Ref erence[@name='invoicer _name']/@value,
            > '+',
            > Reference[@name='invoicer ef']/@value
            > )"/>
            > <xsl:template match="/">
            > <Senders>
            > <xsl:for-each select=
            > "/*/*/*/External
            > [generate-id()
            > =
            > generate-id(
            > key('kExtNameRe f',
            > concat(Referenc e[@name='invoicer _name']/@value,
            > '+',
            > Reference[@name='invoicer ef']/@value
            > )
            > )[1]
            > )
            > ]">
            > <Sender>
            > <invoicer_nam e>
            > <xsl:value-of select=
            > "Reference[@name='invoicer _name']/@value"/>
            > </invoicer_name>
            > <invoiceref>
            > <xsl:value-of select=
            > "Reference[@name='invoicer ef']/@value"/>
            > </invoiceref>
            > <Items TotalItems="{
            > count(
            > key('kExtNameRe f',
            > concat(Referenc e[@name='invoicer _name']/@value,
            > '+',
            > Reference[@name='invoicer ef']/@value
            > )
            > )
            > )
            > }"/>
            > </Sender>
            > </xsl:for-each>
            > </Senders>
            >
            > </xsl:template>
            > </xsl:stylesheet>
            >
            > when applied on your source.xml:
            >
            > <Children>
            > <Child>
            > <References>
            > <External>
            > <Reference name="filename" value="1.dat"/>
            > <Reference name="invoicenr " value="1111111"/>
            > <Reference name="invoicer_ name" value="Bill"/>
            > <Reference name="invoicere f" value="bbbbbb"/>
            > </External>
            > </References>
            > </Child>
            > <Child>
            > <References>
            > <External>
            > <Reference name="filename" value="2.dat"/>
            > <Reference name="invoicenr " value="222222"/>
            > <Reference name="invoicer_ name" value="Bill"/>
            > <Reference name="invoicere f" value="bbbbbb"/>
            > </External>
            > </References>
            > </Child>
            > <Child>
            > <References>
            > <External>
            > <Reference name="filename" value="3.dat"/>
            > <Reference name="invoicenr " value="33333"/>
            > <Reference name="invoicer_ name" value="Clinton"/>
            > <Reference name="invoicere f" value="ccccc"/>
            > </External>
            > </References>
            > </Child>
            > </Children>
            >
            > produces the wanted result:
            >
            > <Senders>
            > <Sender>
            > <invoicer_name> Bill</invoicer_name>
            > <invoiceref>bbb bbb</invoiceref>
            > <Items TotalItems="2" />
            > </Sender>
            > <Sender>
            > <invoicer_name> Clinton</invoicer_name>
            > <invoiceref>ccc cc</invoiceref>
            > <Items TotalItems="1" />
            > </Sender>
            > </Senders>
            >
            >
            > Hope this helped.
            >
            > Cheers,
            > Dimitre Novatchev
            >
            >[/color]


            Comment

            • Dimitre Novatchev

              #7
              Re: Help on xslt - grouping


              "Per Jørgen Vigdal" <per.jorgen.vig dal@ergo.no> wrote in message
              news:1116597174 .198935@makrell .interpost.no.. .[color=blue]
              > This is great, exactly what I want. Thank you.
              > This is goanna be tested in QA 22. Mai and if successful, put into
              > production on 25. Mai where the
              > xsl will do transformation on files that are as big as 100MB with
              > thousands
              > of items[/color]

              Good luck, and it would be interesting if you share your experience (or if
              you have any problems -- just signal) to the newsgroups (and the xsl-list).


              Cheers,
              Dimitre Novatchev


              Comment

              Working...