cancel
Showing results for 
Search instead for 
Did you mean: 

Sorting fields for a group

Former Member
0 Kudos

Hi All,

I am facing a issue while sorting records from source.I have a structure like this -

<node>

<aa>13</aa>

<bb>200</bb>

</node>

<node>

<aa>16</aa>

<bb>200</bb>

</node>

<node>

<aa>14</aa>

<bb>100</bb>

</node>

<node>

<aa>12</aa>

<bb>100</bb>

</node>

My target Structure should be -

<node>

<aa>14</aa>

<bb>100</bb>

</node>

<node>

<aa>12</aa>

<bb>100</bb>

</node>

<node>

<aa>13</aa>

<bb>200</bb>

</node>

<node>

<aa>16</aa>

<bb>200</bb>

</node>

I have to check the last occurence of each different <bb>.Now for this last occurrence, check value of <aa>.Lower the value of <aa>, whole group for that <bb> should comes first in sequence for target structure.

Please provide inputs how to achieve this.

Thanks,

Marz

Accepted Solutions (1)

Accepted Solutions (1)

former_member206760
Active Contributor
0 Kudos

marz,

did u try implementing the ABAP mapping program

Answers (2)

Answers (2)

former_member206760
Active Contributor
0 Kudos
mapping for node : node

mape source node -> target node

mapping for node aa :

context of aa and bb should be set to the top node i.e msg type.
bb--------|
          |-------sort by key---------|
aa--------|                           |                                                                                
|---format by example--sort-- splitbyvalue each val---aa 
                                      |                                                 
bb--sort---split by val(val chnge)----|



maping for node bb:

context of bb should be set to the top node i.e msg type.

bb---sort---split by value each val ---bb.

this one is working for me and should surely work for you as well.

Giving points is another way to say thanks

Edited by: Tarang Shah on Mar 22, 2009 12:10 PM

Former Member
0 Kudos

Hi Tarang,

Thanks for inputs.I have just tried the mapping suggested by you.

But it doesn't produce the required target structure as posted by me..

Thanks,

Marz

Shabarish_Nair
Active Contributor
0 Kudos

try making use of sort and sortbykey functions to help you.

http://help.sap.com/saphelp_nw04/helpdata/en/43/c4cdfc334824478090739c04c4a249/content.htm

Former Member
0 Kudos

Thanks Shabarish, I have tried possible combinations with that...

But using them , will give structure something like this -

<node>

<aa>12</aa>

<bb>100</bb>

</node>

<node>

<aa>13</aa>

<bb>200</bb>

</node>

<node>

<aa>14</aa>

<bb>100</bb>

</node>

<node>

<aa>16</aa>

<bb>200</bb>

</node>

But, I need target structure in below format-

<node>

<aa>14</aa>

<bb>100</bb>

</node>

<node>

<aa>12</aa>

<bb>100</bb>

</node>

<node>

<aa>13</aa>

<bb>200</bb>

</node>

<node>

<aa>16</aa>

<bb>200</bb>

</node>

Thanks,

Marz

prateek
Active Contributor
0 Kudos

Have you tried to use the same sort function twice once for aa and then for bb.

Regards,

Prateek

Former Member
0 Kudos

Prateek,

I have tried, but not able to produce required target structure posted by me...

I have to check the last occurence of each different <bb> in source structure.

Say, for my source structure provided, it will be

<node>

<aa>16</aa>

<bb>200</bb> - last part - out of two ocurrences with <bb> value 200

</node>

<aa>12</aa>

<bb>100</bb> - last part - out of two ocurrences with <bb> value 100

</node>

Now for these two last occurrence for <bb> with 100 & 200, check value of <aa>.Lower the value of <aa>, as <12> is lower than <16>,whole group for that <bb> should comes first in sequence for target structure.

Means whole group for <bb> with 100 value here should come first in target structure..

<node>

<aa>14</aa>

<bb>100</bb>

</node>

<node>

<aa>12</aa>

<bb>100</bb>

</node>

<node>

<aa>13</aa>

<bb>200</bb>

</node>

<node>

<aa>16</aa>

<bb>200</bb>

</node>

I hope i m able to put my requirement clear..here..

Thanks,

Marz

prateek
Active Contributor
0 Kudos

Ok. Instead of using the sort fucntion twice in the same message mapping, you may try to use two message mapping, one sort function in each mapping. You may then use it as a part of same interface mapping.

Regards,

Prateek

Former Member
0 Kudos

Prateek,

I am not clear with explanations...if u can explain with more details & which part of transformation to implement in first & second message mapping respectively..it would be much more than helpful...

Thanks,

Marz

prateek
Active Contributor
0 Kudos

You will have two mappings. In the first one, use sort function to change the source structure to target structure sorted by aa. Now this target structure would act as an intermediate structure. Then in second mapping, use sort function for bb and map it to the similar target structure. Use both the mappings in Interface mapping. In interface mapping, you can add multile mappings at the place where you select the message mapping name.

Regards,

Praeteek

Former Member
0 Kudos

Thanks Prateek,

But this way, it willn't sort it in groups of <bb>, the way it is required for target structure.

Thanks,

Marz

Former Member
0 Kudos

Hi Experts,

Please provide inputs if we can achieve this in graphical mapping or we need to go for Java/XSLT Mapping..

Thanks,

Marz

markangelo_dihiansan
Active Contributor
0 Kudos

Hi Marz,

You can try using this mapping:

For the node aa:


aa--> removeContext --> sortByKey: numericalAscending --> splitByValue --> aa
bb--> removeContext --> /

For the node bb:


bb--> removeContext --> sort: numericalAscending --> splitByValue --> bb

The output is now:

<node>

<aa> 12 </aa>

<bb> 100 </bb>

</node>

<node>

<aa> 14 </aa>

<bb> 100 </bb>

</node>

<node>

<aa> 13 </aa>

<bb> 200 </bb>

</node>

<node>

<aa> 16 </aa>

<bb> 200</bb>

</node>

Problem is 12 and 14 have been interchanged (although they have the same bb) because of sort function. I guess 14 and 12 is impossible to achieve.

Hope this helps,

Former Member
0 Kudos

hi,

to achieve this you have to use UDF, if you have java knowledge you can write the UDF and achive this.

i will give the steps to achive try in this fashion as i dont have server to execute and give whole code.

1) take aa and remove context

2) take bb and remove context

3) give both of them to udf as input.

4) UDF CODE

Mapping bb values

a) take aa into one array

b) take bb into one array

c) assign index in such a way 13_1,13_2... like that for both aa and bb.

d) take bb and use string tokenizer as _ and sort the bb values.

e) now u will get the sorted values of bb with the underscores..

f) now take the values of bb in the same sored order and remove undersore values.

g)now map result.addvalue(bb) to target bb values.

Mapping aa values

a) take the same UDF code agin and follow steps a to e.

b) now take the index values of bb (i.e) values after underscore , compare with aa get the exact corresponding values.

c)now map result.addvalue(aa) to target aa values

This will surely help for you to solve the problem

Thank You,

Madhav

Note: Points If Useful.

former_member206760
Active Contributor
0 Kudos

Marz,

Here is the ABAP mapping program addressing your exact requirement.

to create it go to se24..give a class name say ZABC ...say create and then save it..

in the interfaces tab type if_mapping and press enter then go to methods tab there you will find the execute method . double click on it and paste the code below...

just take care that you replace the target message type(MT_T) that i have given with your target message type .

method IF_MAPPING~EXECUTE.

* initialize iXML

  type-pools: ixml.

  class cl_ixml definition load.

* create main factory

  data: ixmlfactory type ref to if_ixml.

  ixmlfactory = cl_ixml=>create( ).

* create stream factory

  data: streamfactory type ref to if_ixml_stream_factory.

  streamfactory = ixmlfactory->create_stream_factory( ).

* create input stream

  data: istream type ref to if_ixml_istream.

  istream = streamfactory->create_istream_xstring( source ).

* parse input document ==============================================

* initialize input document

  data: idocument type ref to if_ixml_document.

  idocument = ixmlfactory->create_document( ).

* parse input document

  data: iparser type ref to if_ixml_parser.

  iparser = ixmlfactory->create_parser(
                            stream_factory = streamfactory
                            istream = istream
                            document = idocument ).

  iparser->parse( ).

  data: val1 type string,
        val2 type string.

  data:elementsend type ref to if_ixml_element,
       elementsender1 type ref to if_ixml_element,
       elementsender2 type ref to if_ixml_element,
       elementsender3 type ref to if_ixml_element.


  data  : begin of temp,
         aa type string,
         bb type string,
         end of temp.

  data : wa like temp.

  data : temp1 like standard table of temp,
         temp2 like standard table of temp.
  data: odocument type ref to if_ixml_document.
  data: node6 type ref to if_ixml_node_list,
        node7 type ref to if_ixml_node_list,
        child5 type ref to if_ixml_node,
        child7 type ref to if_ixml_node,
        index type i,
        index1 type i,
        index2 type i.
  odocument = ixmlfactory->create_document( ).

  data: element type ref to if_ixml_element.

  elementsend = odocument->create_simple_element( name = 'MT_T'
                                           parent = odocument ).

  element = IDocument->get_root_element( ).

  clear index.

  node6 = element->get_children( ).
*
*  while not child is initial.
  while index < node6->get_length( ).

    child5 = node6->get_item( index ).


    if child5->get_name( ) = 'node'.

      node7 = child5->get_children( ).

      clear index1.

      while index1 < node7->get_length( ).

        child7 = node7->get_item( index1 ).


        if child7->get_name( ) = 'aa'.

          val1 = child7->get_value( ).


        endif.

        if child7->get_name( ) = 'bb'.

          val2 = child7->get_value( ).


        endif.

        temp-aa = val1.

        temp-bb = val2.

        index1 = INDEX1 + 1.

      endwhile.

    endif.

    append temp to temp1.

    clear temp.

    INDEX = INDEX + 1.

  endwhile.

  temp2[] = temp1[].

  sort temp1 by bb ascending aa ascending.

  delete adjacent duplicates from temp1 comparing bb.

  loop at temp1 into temp.

    loop at temp2 into wa where bb = temp-bb.


      elementsender1 = odocument->create_simple_element(
                                                 name = 'node'

                       parent = elementsend ).

      elementsender2 = odocument->create_simple_element(
                                                 name = 'aa'
                       value = wa-aa
                       parent = elementsender1 ).

      elementsender3 = odocument->create_simple_element(
                                                  name = 'bb'
                        value = wa-bb
                        parent = elementsender1 ).


    endloop.

  endloop.

* create output stream

  data: ostream type ref to if_ixml_ostream,
  IRC TYPE I.

  ostream = streamfactory->create_ostream_xstring( result ).

* create renderer

  data: renderer type ref to if_ixml_renderer.

  renderer = ixmlfactory->create_renderer(
                              ostream = ostream
                              document = odocument ).

  irc = renderer->render( ).

endmethod.

save and activate ....after that give the class name ZABC in the interface mapping after selecting ABAP class in the mapping options.

This will work as per your requirement

Former Member
0 Kudos

Hi Tarang,

Sorry for late reply....

Appreciate your effort for solving it by using ABAP mapping...Awarding points for that

But, i can't use it due to design constraints..ABAP mapping isn't preferred.

I solved it by using an advanced user defined functions with a simple logic.

I first read last occurence for each of different value of <bb> with standard graphical functions & then did the sorting between those two different values of <bb> fields,.

This will give me output as -

<node>

<aa>12</aa>

<bb>100</bb>

<node>

<node>

<aa>16</aa>

<bb>200</bb>

<node>

After that , when i get to know of exact sequence for field <bb> i.e 100 & 200, i read all records from source having <bb> value 100 & then read all records from source having <bb> value 200.

Thanks,

Marz

Former Member
0 Kudos

Thanks Madhav & all for providing inputs to solve it out.

Thanks,

Marz