on 03-22-2009 5:54 AM
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
marz,
did u try implementing the ABAP mapping program
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
try making use of sort and sortbykey functions to help you.
http://help.sap.com/saphelp_nw04/helpdata/en/43/c4cdfc334824478090739c04c4a249/content.htm
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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,
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
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
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,
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.
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
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
User | Count |
---|---|
89 | |
10 | |
9 | |
9 | |
9 | |
6 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.