Many a times, you are required to convert flat file structures to deeply nested structures like IDocs. Standard File Content Conversion allows you to convert the incoming file to flat XML structures only i.e. only one level of nesting is possible. Converting incoming file to deeply nested structures would require use of either custom developed adapter modules or third-party conversion agents.
This article provides a workaround to accomplish the same thing by using only the graphical mapping. William had a similar requirement, and we came up with a generic solution which is described below.
Lets say we have an incoming flat file with structure as described below –
Node1 – Occurs 0..1
Node2 – Occurs 0..unbounded
Node3 – Occurs 0..unbounded
Node4 – Occurs 0..unbounded
And the target structure is as shown below –
Node1 – Occurs 0..1
Node2 – Occurs 0..unbounded
Node3 – Occurs 0..unbounded and repeats under the preceding Node2
Node4 – Occurs 0..unbounded and repeats under the preceding Node3
Due to limitation of the standard File adapter, it is not possible to directly convert the incoming file to the deeply nested target structure. Hence we will use a two step message mapping to attain the required result.
First, we will use file content conversion as shown to covert the incoming file to flat XML structure as supported by the adapter. Click the image on the right to see an enlarged view. We will then use two-step message mapping to convert the flat XML to a nested XML. Figure below shows the flat XML structure generated by the file adapter using file content conversion.
Our aim is to convert the above flat structure to a nested shown below –
Note that there is no common element between parent and child nodes (e.g. Node2 and Node3, or Node3 and Node4) which we could use to determine corresponding parent node for each child node.
Hence, we need to create an intermediate message type which will establish a relationship between the parent and child nodes. We have achieved this by adding id attributes to each of the nodes as shown below.
The id attribute is mapped using a user defined function globalCounter which records the order in which the nodes appear in the source structure. The variable used to store the count is a global variable and is incremented every time a node is found in the source structure (irrespective of the node name).
Create one-to-one message mapping between source message and the intermediate message. Map the id attribute in the target with the globalCounter function.
The Java code of the globalCounter function is given below –
public String globalCounter(Container container){
GlobalContainer globalContainer;
globalContainer = container.getGlobalContainer();
Object o = globalContainer.getParameter("count");
Integer i;
if ( o == null ) i = new Integer( 0 );
else i = (Integer)o;
i = new Integer(i.intValue() + 1 );
globalContainer.setParameter("count", i );
return i.toString();
}
Now create another message mapping to map the intermediate message type to the target message type. The message mapping is shown below.
Node 1 is directly mapped to Node1 in the target as this node is not part of any hierarchy. The topmost parent node Node2 is mapped using removeContexts function.
All the nodes appearing below the topmost node (Node3 and Node4 in this case) have been mapped using removeContexts function and user defined nest function as shown below –
The first parameter to the nest function is the id attribute of the parent node while the second parameter is the id attribute of the current node (child node). Both parameters have been first processed with removeContexts function before passing them to the nest function. The third parameter is the actual value of the node that needs to passed on to the target structure. Below is the Java code for the nest function.
public void nest(String[] parent,String[] current,String[] node,ResultList result,Container container){
int i, j;
int a, b, c;
int x;
j = 0;
x = j+1;
for( i = 0; i < current.length; i++ ) {
for (;x<parent.length; j++,x++ ){
a = Integer.parseInt(parent [j]);
b = Integer.parseInt(current [i]);
c = Integer.parseInt(parent [x]);
if ( a < b ) {
if(c > b ) {
result.addValue(node[i]);
break;
}
else if (c < b) {
result.addContextChange();
}
}
}
if (x == parent.length) {
result.addValue(node[i]);
}
}
}
PS: If you are new to the idea of context handling, do read An Introduction to Context Handling.
Once this is done, create an interface mapping between the source and target interface and provide the mapping programs in the correct order i.e. first the mapping between source and intermediate message and then the one between intermediate and target structure. The same is shown below –
Now you can test the interface mapping locally and then test your scenario by doing appropriate directory configuration. Interface mapping test result is shown in the figure below –
Thus, we have seen how we can use plain file adapter and graphical mapping to convert a flat file to a deeply nested XML structure.
This idea could even be extended to convert EDI documents to IDoc structures as an alternative to third-party EDI adapters like Seeburger.
Riyaz,
Blog is very descriptive and very useful. I did the Message mapping and Interface mapping exactly as you described but when I started testing the interface mapping, I am getting the following error message.
Your response is greatly appreaciated.
Runtime exception occurred during execution of application mapping program com/sap/xi/tf/_MM_HCLP_HDOC850_to_ORDERS05bundle_: com.sap.aii.utilxi.misc.api.BaseRuntimeException; RuntimeException in Message-Mapping transformation: Runtime exception during processing target field mapping /ORDERS05/IDOC/E1EDP01/E1EDPT1/E1EDPT2. The message is: Exception:[java.lang.ArrayIndexOutOfBoundsException: 3] in class com.sap.xi.tf._MM_HCLP_HDOC850_to_ORDERS05bundle_ method nest$[com.sap.aii.mappingtool.flib3.Plainer@c2af46, com.sap.aii.mappingtool.flib3.Plainer@18135ac, com.sap.aii.mappingtool.flib3.Plainer@1eacebf]
I think, you are missing “PAYLOAD”, please give payload and test again… :-)
Hi Dharmendra,
Cross check the Java code of your UDFs, especially check the for loops. ArrayIndexOutOfBoundsException indicates that the array is running out of bounds when you are looping through it.
Hope this helps.
Regards,
Riyaz
Riyaz,
Thanks for your comments. In my debugging, I realised that the issue is with Nest function. I think this function designed to support the mandatory nodes (Node1, Node2, Node3 and Node4) on your source mapping and it supports one iteration only. In my case, for every Node1 we can get multiple Node2’s and for every Node2 we can get multiple Node3’s (from 0 to 10). If you have some free time can you help me in fixing the Nest function to support the above requirement. I can provide the sample data for the scenario.
Thanks,
Dharmi.
Dharmi,
The Nest function is designed in this way – The first argument is the list of id attributes of the node under which you want to create a child node (without any context changes), second argument is the list of id attributes of the node you want to nest under the above parent node (without any context changes) and the third argument is the list of values of the child node (again without any context changes).
So in the above example, we have nested Node3 under Node2. Node1 does not come into picture. The nest function is applied to Node3 i.e. id attributes of Node2 is first argument, id attributes of Node3 is second argument and Node3 itself is the third argument. removeContexts() function is used to pass on a contexts free list of values and is applied to all three arguments. Node2 is mapped only with removeContexts() since it is the topmost node in the hierarchy (Note that Node 1 is out of the hierarchy and is a separate node).
Similarly for Node4, we pass id attributes of Node3 and Node4 as first and second argument and Node4 values as third argument with removeContexts() applied to them before passing them to nest() function.
Since Node2, Node3 and Node4 occur 0..unbounded, they can occur any number of times anywhere. So it very supports multiple occurrences. Thus for every Node2, there can be any number of Node3 nodes and for every Node3 there can be any number of Node4 nodes.
Regards,
Riyaz
Thank you very much for your quick and very detailed response. Looks like your fix is working fine.
I need little more time to validate the data and to let you know the fix is working.
Thanks again for your help.
Dharmi.
Hi Riyyaz,
Looks like you are doing a good job for beginers like me
Can you explain me what really the nested loop in nest does, because when I look at it
I have a feeling that X is always j+1. So anything in between will have fraction in it and it will either be truncated down to X or up to J.
so that said
a strictly lesser than b and c strictly greater than b will never occur…… Can you please explain me that logic or send me an email on it.
I will appreciate your help.
Thanks
Shilpa
Hi Shilpa,
Please go thru the explaination of functionality of nest() function explained in previous comment.
We are working with counters here and are integers always. So fractions wont occur. Also, id of child node will always be greater than its corresponding parent node. so b will always be greater than a and c.
Hope this helps.
Regards,
Riyaz
Hi Riyaz,
It looks great to me…
I am also biginner in the SAP XI mapping…
Actually i wanted to convert the deeply nested structure into flat structure…
Any help in this regard will be appreciated….
My mail id is onlyvenkatesh@gmail.com
Regards
Venkatesh
Hi Venkatesh,
You can consider taking a reverse approach to this article to convert from deeply nested structure to a flat structure.
Take a look at this thread for inputs.
Regards,
Riyaz
Hi Riyaz,
Your blog “XI/PI: Convert Flat File to Deeply Nested XML Structures Using Only Graphical Mapping” is really good.
My requirement is exactly the opposite of what you explained. I.e. I need to map nested structure (4 hierarchical level) of IDOC to flat structure.
I will really appreciate you can tell me how to achieve this.
Regards,
Shwetambari.
Hi Shwetambari,
You can consider taking a reverse approach to this article to convert from deeply nested structure to a flat structure.
Take a look at this thread for inputs.
Regards,
Riyaz
Riyaz,
By using the above mentioned approach, I could able to create the deeply nested structures but I am getting the following issue.
I am trying to populate data from source message type to an Intermediate message type (have an additional ID fields in few nodes). Here I am getting the following issue. Because of this issue, value of the ID field in each node is getting varied.
Source Node loop After the Transform
PO PO
PID, PO
SCH PO
PO, PID
PID, PID
SCH, PID
NTE2, SCH
PO, SCH
PID, SCH
SCH NTE2
I couldn’t find any simpler way to resolve this issue. Please suggest me if you know any.
Thanks,
Dharmi.
Hi Dharmi,
I could not understand the issue you are facing. From what I understand, make sure you are using a global variable to store the ID values. If the variable is local, it would behave just like the standard counter function.
Regards,
Riyaz
Riyaz,
Sorry, I might have explained the issue clearly. I used the globalContainer to populate the value for ID variable. I used your sample code to populate the value for ID.
In the Input message, One of the order contains the nodes order like below
CC,PO1,PID1,SCH1,PO2,PID2,SCH2,NTE2,PO3,PID3,SCH3
Whne I transform the message, I am getting the following order
CC,PO1,PO2,PO3,PID1,PID2,PID3,SCH1,SCH2,SCH3,NTE2
Note: In the above example 1,2,3 are used just to explain the issue properly.
As per the input message, Value of the ID element in NTE2 segment supposed to be ‘8’ if it follows the correct order but because of the above issue, ID element is getting the value as ’11’. This is creating the problem while creating the IDOC in R/3. Note is getting created for a different PO.
I hope I explained the issue but if you need more details then I can send them to your e-mail. Please provide your e-mail ID.
Your help is greatly appreciated.
Thanks,
Dharmi.
Hi Dharmi,
This is probably because of the way the XML is processed by XI. As I understand, you are trying to assign ID values to nodes whose parent nodes are different.
In my case, if you observe, Node1,2,3,4 all have a common parent (Recordset) i.e. its a flat structure. So it gets processed in the correct sequence.
If you dont have a flat structure, you can consider twicking the UDF code a bit or try using a separate copy of globalCounter function for every different outer node (In my case Recordset is the outer node). By separate copy I mean something like globalCounter1, globalCounter2,… etc.
Hope this helps.
Regards,
Riyaz
Riyaz,
All the nodes are at same level. Parent node is Orders for all these nodes. My scenario is exactly like your example but I think your test data doesn’t have different occurances for the nodes. I have seen few people mentioned about XSLT mapping for these kind of issues but do you have any samples.
Thanks,
Dharmi.
Riyaz,
I can send couple of screen prints to explain the issue in a better way but I need your e-mail ID for that. please let me know.
Thanks,
Dharmi.
you can write to me at riyaz at riyaz.net
Hi Riyaz, Nice blog and trying to fit it for my scenerio. I am working on a scenerio for which source is mainframe file to Idoc Order05. I tried applying the above logic. It worked fine, but not exactly fit into my scenerio. My scenerio needs parent node “node1” should be 0 to unbound.
Node1 – Occurs 0..unbounded
Node2 – Occurs 0..unbounded
Can you suggest modification to your code? I appreciate your help in this regard.
Thanks
Ram
Hi Ram,
In my case Node1 is out of the hierarchy. Only Node2, Node3 and Node4 are nested under one another. And all the three are 0..unbounded. So I guess this solves your problem.
Let me know if I did not understand your concern correctly.
Thanks.
Regards,
Riyaz
Riyaz,
I sent an e-mail to you couple of days back with details of my issue. Please let me know if you find any solution.
Regards,
Dharmi.
Hey Dharmi,
Replied to your mail. Let me know if it helps.
Regards,
Riyaz
Hi Riyaz,
Nice Blog… But Iam also facing problem similar to Dharmis problem…
(( Dharmi
Posted September 16, 2008 at 2:16 am | Permalink
Riyaz,
I can send couple of screen prints to explain the issue in a better way but I need your e-mail ID for that. please let me know.
Thanks,
Dharmi. ))
What suggestion you provided to him?
Thanks,
Amol
Hi Riyaz
When i tried the Global Counter UDF i am getting the error..
the length 0 of the array ‘sortedFunctionKeys’ is not equal to the number 1 of functions.
Any idea why i am getting that..
What is array sortedFunctionKeys? Check code of the UDF where this array is used. Possibly the array is not initialized or has no elements.
Hi Riyaz
I fixed the error.. But i am getting the error .. when i duplicate the Node2 and Node3 and Node4..
Runtime exception when processing target-field mapping /ns0:MT_GLAccountPosting_GE/HeaderInfo/GLInfo; root message: Exception:[java.lang.NumberFormatException: For input string: “”] in class com.sap.xi.tf._MM_GLAccountPostingIntermediate_GLPostingGE_ method nest[[Ljava.lang.String;@420357b9, [Ljava.lang.String;@6974548a, [Ljava.lang.String;@545a661c, com.sap.aii.mappingtool.tf7.rt.ResultListImpl@7ae5e387, com.sap.aii.mappingtool.tf7.rt.Context@abcf31a]
Hi Vaccu,
NumberFormatException might occur if you are passing empty string to a function that expects a number as a parameter. Check where this could be happening and you should be able to resolve the issue.
Hello Riyaz,
I thought this suggestion might help some of your readers. If you have a flat file in the form of:
File_Header
Order-header 1
order1line 1
order1line 2
Order-header 2
order2line 1
order2line 2
order2line 3
Footer
If you need this as a two level xml file with multiple nodes at detail header level and associated line items immediately following, you can set the adapter config to something like:
FILE_HEADER,1,ORDER_HEADER,1,ORDER_DETAIL,*,FOOTER,*
This seems to make the footer optional and wrap the file into a nicely separated heirarchy with a new recordset for each Order_Header
Regards,
Aaron
Hi Riyaz,
that was a good blog. can we do the the same for the vice versa scenario. means can we convert the deeply nested structure to a flat file? if so, kinldy let me know
Best Regards
Deepika
Thats very much possible. See my reply here.
Hi Riyaz
Thank you for the information. But I am getting an error for global container UDF.
the error is “Invalid start of expression” and the indication is at 1st line of code.
I don’t know java, please give your inputs to solve the error. thanks
Hi Riyaz
I am trying to implement above well described scenario but facing issue. Please find my requirement detail below
Flat File Structure
Header (1) -> Record (1…unbounded) -> Forecast (1…unbounded)
Example of input file
Header (Topmost node)
Record 1 (should come under Header)
Forecast 11 (should come under record 1)
Forecast 12 (should come under record 1)
Record 2 (should come under Header)
Forecast 21 (should come under record 2)
Forecast 21 (should come under record 2)
It works fine if there is only 1 record row and multiple Forecast rows but it gives runtime error when I there is input of multiple record rows.
Please let me know you inputs to solve the issue. I really appreciate your knowledge sharing. Thanks
Regards
Amol
Amol,
Check the globalContainer UDF code. there could be typographic error. Copy and paste the code from the above code snippet. For your requirement, I guess the code given in this article for nest function should work without modifications. Header correspods to Node2 and Record correpsonds to Node3 while Forecast corresponds to Node4 in the article. Ensure that you do graphical mapping correctly as shown.
Hi Riyaz
I have corss checked the mapping and its exactly same as you have mentioned above, here is the error i am getting when i send more than one record row
RuntimeException during appliction Java mapping com/sap/xi/tf/__
com.sap.aii.mappingtool.tf7.IllegalInstanceException: Cannot create target element /ns1:ProductActivityNotification/ProductActivity/Item[2]/Product. Values missing in queue context. Target XSD requires a value for this element, but the target-field mapping does not create one. Check whether the XML instance is valid for the source XSD, and whether the target-field mapping fulfils the requirement of the target XSD at com.sap.aii.mappingtool.tf7.AMappingProgram.processNode(AMappingProgram.java:366) at com.sap.aii.mappingtool.tf7.AMappingProgram.processNode(AMappingProgram.java:406) at com.sap.aii.mappingtool.tf7.AMappingProgram.processNode(AMappingProgram.java:406) at com.sap.aii.mappingtool.tf7.AMappingProgram.processNode(AMappingProgram.java:406) at com.sap.aii.mappingtool.tf7.AMappingProgram.start(AMappingProgram.java:496) at com.sap.aii.mappingtool.tf7.Transformer.start(Transformer.java:133) at com.sap.aii.mappingtool.tf7.AMappingProgram.transform(AMappingProgram.java:626) at com.sap.aii.ib.server.mapping.execution.JavaMapping.executeStep(JavaMapping.java:92) at com.sap.aii.ib.server.mapping.execution.Mapping.execute(Mapping.java:60) at com.sap.aii.ib.server.mapping.execution.SequenceMapping.executeStep(SequenceMapping.java:40) at com.sap.aii.ib.server.mapping.execution.Mapping.execute(Mapping.java:60) at com.sap.aii.ib.server.mapping.execution.MappingHandler.map(MappingHandler.java:87) at com.sap.aii.ib.server.mapping.execution.MappingHandler.map(MappingHandler.java:54) at com.sap.aii.ibrep.server.mapping.rt.MappingHandlerAdapter.run(MappingHandlerAdapter.java:139) at com.sap.aii.ibrep.server.mapping.exec.ExecuteIfMapCommand.execute(ExecuteIfMapCommand.java:33) at com.sap.aii.ib.server.mapping.exec.CommandManager.execute(CommandManager.java:43) at com.sap.aii.ibrep.server.mapping.ServerMapService.execute(ServerMapService.java:40) at com.sap.aii.ibrep.server.mapping.MapServiceBean.execute(MapServiceBean.java:40) at sun.reflect.GeneratedMethodAccessor824.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at com.sap.engine.services.ejb3.runtime.impl.RequestInvocationContext.proceedFinal(RequestInvocationContext.java:43) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:166) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_StatesTransition.invoke(Interceptors_StatesTransition.java:19) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Resource.invoke(Interceptors_Resource.java:71) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Transaction.doWorkWithAttribute(Interceptors_Transaction.java:38) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Transaction.invoke(Interceptors_Transaction.java:22) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:189) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_StatelessInstanceGetter.invoke(Interceptors_StatelessInstanceGetter.java:16) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_SecurityCheck.invoke(Interceptors_SecurityCheck.java:21) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_ExceptionTracer.invoke(Interceptors_ExceptionTracer.java:16) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.DefaultInvocationChainsManager.startChain(DefaultInvocationChainsManager.java:133) at com.sap.engine.services.ejb3.runtime.impl.DefaultEJBProxyInvocationHandler.invoke(DefaultEJBProxyInvocationHandler.java:164) at $Proxy1579.execute(Unknown Source) at sun.reflect.GeneratedMethodAccessor823.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at com.sap.engine.services.rmi_p4.P4DynamicSkeleton.dispatch(P4DynamicSkeleton.java:234) at com.sap.engine.services.rmi_p4.DispatchImpl._runInternal(DispatchImpl.java:351) at com.sap.engine.services.rmi_p4.server.ServerDispatchImpl.run(ServerDispatchImpl.java:70) at com.sap.engine.services.rmi_p4.P4Message.process(P4Message.java:62) at com.sap.engine.services.rmi_p4.P4Message.execute(P4Message.java:37) at com.sap.engine.services.cross.fca.FCAConnectorImpl.executeRequest(FCAConnectorImpl.java:872) at com.sap.engine.services.rmi_p4.P4Message.process(P4Message.java:53) at com.sap.engine.services.cross.fca.MessageReader.run(MessageReader.java:58) at com.sap.engine.core.thread.execution.Executable.run(Executable.java:108) at com.sap.engine.core.thread.execution.CentralExecutor$SingleThread.run(CentralExecutor.java:304)
Please give your inputs to solve the issue
Hi Riyaz
Please let me know your inputs. Thanks.
try testing locally in IR. Probably the namespace of the source XML may not be correct, i.e as per the source xsd.
Thanks! Its realy cool. I think you make realy hard work.
Hi Riyaz,
Thanks for all your wonderful information.
We have requirement of hierarchial mapping from IDOC to fIe and File to IDOC .
I have seen your blog. I got struck at one point.
I would like to know, how to do first level mapping.. is it same as flat file.. then do
hierarchial map of source with Id’s( as per your blog ) with target IDOc.
Please help me if with any detail documents or screenshots of both scenarios.
Thanks in Advance.
Vishnu
In my example, there is no nesting for node1. Multiple level nesting starts with Node2. Node3 is child of Node2 while Node4 is child of Node3. But Node2 is not child of Node1. This is just an example. You may need to adapt the mapping as per the target structure you need to derive.
Hi Riyaz,
I want to populate my fields in header line on receiver file adapter
let say 2 fields
Countey , City
India,Bangalore
UK,London
Sweden,Stockholm
Japan,tokoyo
How can we achive this??
Waiting for your reply.
Abhay,
Can you please elaborate your question. What is the source structure and what is the target structure you are trying to map to?
Hi Riyaz,
This one is really cool blog. Just reviwed my old SAP XI skills which was quiet washed away in last couple of months :-) :-)
Thanks
Abhishek
Thank you Abhishek. Glad that you liked my blog :)
Hi Riyaz
My first question is when applying code for global Container UDF to attribute SEQ the count should be like the one given below or anything else:
Header – 1
Detail – 2
Weight – 3
Weight – 4
Detail – 5
Weight – 6
Weight – 7
Trailer
OR like the one I am getting below:
Header – 1
Detail – 2
Detail – 3
Weight – 4
Weight – 5
Weight – 6
Weight – 7
Trailer
Can this be a problem.
off course the first one is correct
Hi Riyaz
But the code is giving the following output
Header – 1
Detail – 2
Detail – 3
Weight – 4
Weight – 5
Weight – 6
Weight – 7
Trailer
This is the code:
public String globalCounter(Container container){
GlobalContainer globalContainer;
globalContainer = container.getGlobalContainer();
Object o = globalContainer.getParameter(“count”);
Integer i;
if ( o == null ) i = new Integer( 0 );
else i = (Integer)o;
i = new Integer(i.intValue() + 1 );
globalContainer.setParameter(“count”, i );
return i.toString();
}
I have sent you an Email with an attachment. Could you please check it.
Regards
Neha
Hi Riyaz
I have a simillar requirement and I tried ur global container and nest function but i am
still not getting the appropriate response. My source structure is after content conversion
is:
Header — 0…1
Detail — 0..unbounded
Weights — 0..unbounded
trailer — 0…1
and i want to convert it to the following target:
Header — 0…1
Detail — 0..unbounded
Weights — 0..unbounded (repeats under preceding node detail)
trailer — 0…1
To acheive this I made one mapping MM_Intermediate where source and target were as given
below and I added the global container UDF provided by you as it is and target came out like
this:
————-Source————–
ns: MT_REQ
header
…………
/header
Detail
……..
……..
/Detail
Weight
……..
……….
/Weight
Weight
……….
………..
/Weight
Detail
……..
……..
/Detail
Weight
……..
……….
/Weight
Weight
……….
………..
/Weight
trailer
………
/trailer
——Target——– After applying the UDF
ns: MT_Intermediate
header>
…………
/header
Detail
SEQ —- value 1
……..
/Detail
Detail
SEQ —- value 2
……..
/Detail
Weight
SEQ —- value 3
……….
/Weight
Weight
SEQ —- value 4
………..
/Weight
Weight
SEQ —- value 5
……….
/Weight
Weight
SEQ —- value 6
………..
/Weight
trailer
………
/trailer
And finally i made the message mapping MM_Target where I mapped the above response to the
IDOC to achieve this as final target:
NOTE: I added SEQ of of Detail, SEQ of Weights and Weights to the UDF “nest” but all
the weights are getting shifted to the second detail.
<ns: MT_Target
header
…………
/header
Detail
Weight
……….
/Weight
Weight
……….
/Weight
/Detail
Detail
Weight
……….
/Weight
Weight
……….
/Weight
/Detail
trailer
………
/trailer
My code for UDF nest is this:
public void nest(String[] parent,String[] current,String[] node,ResultList result,Container
container){
int i, j;
int a, b, c;
int x;
j = 0;
x = j+1;
for( i = 0; i < current.length; i++ ) {
for (;x<parent.length; j++,x++ ){
a = Integer.parseInt(parent [j]);
b = Integer.parseInt(current [i]);
c = Integer.parseInt(parent [x]);
if ( a b ) {
result.addValue(node[i]);
break;
}
else if (c < b) {
result.addContextChange();
}
}
}
if (x == parent.length) {
result.addValue(node[i]);
}
}
}
I don't have much knowledge of Java. Please help.
I am waiting for your reply.
Thanks
Neha
I guess you need to revisit and make sure that the contexts used for individual nodes are giving correct results. If not, you can try changing the contexts. To do this, make sure you have a source xml in the test tab of your mapping editor. Then on design tab, right click each node function, say removeContexts, nest etc and choose Display Queue to see if the conversion is as desired. If not, you can change the contexts of source elements by right-clicking and choosing appropriate context. For more details on context handling see https://www.riyaz.net/blog/xipi-introduction-to-context-handling-in-message-mapping/technology/sap/5/
I would also suggest using tool like NWDS or eclipse to further debug the Java code.
If you are getting a specific output that is because of the input data you are passing. The code will add the counters in the same sequence as the source data. Either change your source data and test or then chnage the code to suit your requirements.
Hihi guys, long time lurker first time poster here
pleased to be a member, and I look forward to begin getting more active here
For now take a look at my site http://articlewriter.websex7.com/?p=3
Hi Riyaz,
Hope you are having a good time.
I am stuck with one error in SXMB_MONI_BPE. We did the upgrade of objects from XI production to PI. The interface working in XI is not working in PI. This is showing up an error in BPE monitoring. Error is
–
Mapping http://fuelGoodsIssue.sap.dominofoods.com IM_FUELFILE_2_FUELVAL_REQUEST , Software Component Version A8A25E80F59011DAC55BEE540ADE8788
Mapping Step 1 , Type JAVA , Program com/sap/xi/tf/_MM_FUELFILE_2_FUELVAL_REQUEST_
RuntimeException during appliction Java mapping com/sap/xi/tf/_MM_FUELFILE_2_FUELVAL_REQUEST_ Thrown: com.sap.aii.mappingtool.tf7.IllegalInstanceException: Cannot create target element /ns1:Z_FUEL_VAL_UPDATE_PROCESS/PCFILE. Values missing in queue context. Target XSD requires a value for this element, but the target-field mapping does not create one. Check whether the XML instance is valid for the source XSD, and whether the target-field mapping fulfils the requirement of the target XSD at com.sap.aii.mappingtool.tf7.AMappingProgram.processNode(AMappingProgram.java:369) at com.sap.aii.mappingtool.tf7.AMappingProgram.processNode(AMappingProgram.java:411) at com.sap.aii.mappingtool.tf7.AMappingProgram.start(AMappingProgram.java:503) at com.sap.aii.mappingtool.tf7.Transformer.start(Transformer.java:134) at com.sap.aii.mappingtool.tf7.AMappingProgram.transform(AMappingProgram.java:635) at com.sap.aii.ib.server.mapping.execution.JavaMapping.executeStep(JavaMapping.java:92) at com.sap.aii.ib.server.mapping.execution.Mapping.execute(Mapping.java:60) at com.sap.aii.ib.server.mapping.execution.MappingHandler.map(MappingHandler.java:87) at com.sap.aii.ib.server.mapping.execution.MappingHandler.map(MappingHandler.java:71) at com.sap.aii.ibrun.sbeans.mapping.MappingRequestHandler.handleMappingRequest(MappingRequestHandler.java:119) at com.sap.aii.ibrun.sbeans.mapping.MappingRequestHandler.handleRequest(MappingRequestHandler.java:72) at com.sap.aii.ibrun.sbeans.mapping.MappingServiceImpl.processFunction(MappingServiceImpl.java:79) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:592) at com.sap.engine.services.ejb3.runtime.impl.RequestInvocationContext.proceedFinal(RequestInvocationContext.java:46) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:166) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_StatesTransition.invoke(Interceptors_StatesTransition.java:19) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Resource.invoke(Interceptors_Resource.java:71) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Transaction.doWorkWithAttribute(Interceptors_Transaction.java:38) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Transaction.invoke(Interceptors_Transaction.java:22) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:189) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_StatelessInstanceGetter.invoke(Interceptors_StatelessInstanceGetter.java:16) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_SecurityCheck.invoke(Interceptors_SecurityCheck.java:21) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_ExceptionTracer.invoke(Interceptors_ExceptionTracer.java:16) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.DefaultInvocationChainsManager.startChain(DefaultInvocationChainsManager.java:133) at com.sap.engine.services.ejb3.runtime.impl.DefaultEJBProxyInvocationHandler.invoke(DefaultEJBProxyInvocationHandler.java:164) at $Proxy982.processFunction(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:592) at com.sap.engine.services.rfcengine.RFCDefaultRequestHandler.handleRequest(RFCDefaultRequestHandler.java:183) at com.sap.engine.services.rfcengine.RFCJCOServer$J2EEApplicationRunnable.run(RFCJCOServer.java:267) at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37) at java.security.AccessController.doPrivileged(Native Method) at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:182) at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:280)
Runtime Exception when executing application mapping program com/sap/xi/tf/_MM_FUELFILE_2_FUELVAL_REQUEST_; Details: com.sap.aii.mappingtool.tf7.IllegalInstanceException; Cannot create target element /ns1:Z_FUEL_VAL_UPDATE_PROCESS/PCFILE. Values missing in queue context. Target XSD requires a value for this element, but the target-field mapping does not create one. Check whether the XML instance is valid for the source XSD, and whether the target-field mapping fulfils the requirement of the target XSD Thrown: com.sap.aii.ib.core.mapping.execution.ApplicationRuntimeException: Runtime Exception when executing application mapping program com/sap/xi/tf/_MM_FUELFILE_2_FUELVAL_REQUEST_; Details: com.sap.aii.mappingtool.tf7.IllegalInstanceException; Cannot create target element /ns1:Z_FUEL_VAL_UPDATE_PROCESS/PCFILE. Values missing in queue context. Target XSD requires a value for this element, but the target-field mapping does not create one. Check whether the XML instance is valid for the source XSD, and whether the target-field mapping fulfils the requirement of the target XSD at com.sap.aii.ib.server.mapping.execution.JavaMapping.executeStep(JavaMapping.java:118) at com.sap.aii.ib.server.mapping.execution.Mapping.execute(Mapping.java:60) at com.sap.aii.ib.server.mapping.execution.MappingHandler.map(MappingHandler.java:87) at com.sap.aii.ib.server.mapping.execution.MappingHandler.map(MappingHandler.java:71) at com.sap.aii.ibrun.sbeans.mapping.MappingRequestHandler.handleMappingRequest(MappingRequestHandler.java:119) at com.sap.aii.ibrun.sbeans.mapping.MappingRequestHandler.handleRequest(MappingRequestHandler.java:72) at com.sap.aii.ibrun.sbeans.mapping.MappingServiceImpl.processFunction(MappingServiceImpl.java:79) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:592) at com.sap.engine.services.ejb3.runtime.impl.RequestInvocationContext.proceedFinal(RequestInvocationContext.java:46) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:166) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_StatesTransition.invoke(Interceptors_StatesTransition.java:19) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Resource.invoke(Interceptors_Resource.java:71) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Transaction.doWorkWithAttribute(Interceptors_Transaction.java:38) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Transaction.invoke(Interceptors_Transaction.java:22) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:189) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_StatelessInstanceGetter.invoke(Interceptors_StatelessInstanceGetter.java:16) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_SecurityCheck.invoke(Interceptors_SecurityCheck.java:21) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.Interceptors_ExceptionTracer.invoke(Interceptors_ExceptionTracer.java:16) at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177) at com.sap.engine.services.ejb3.runtime.impl.DefaultInvocationChainsManager.startChain(DefaultInvocationChainsManager.java:133) at com.sap.engine.services.ejb3.runtime.impl.DefaultEJBProxyInvocationHandler.invoke(DefaultEJBProxyInvocationHandler.java:164) at $Proxy982.processFunction(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:592) at com.sap.engine.services.rfcengine.RFCDefaultRequestHandler.handleRequest(RFCDefaultRequestHandler.java:183) at com.sap.engine.services.rfcengine.RFCJCOServer$J2EEApplicationRunnable.run(RFCJCOServer.java:267) at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37) at java.security.AccessController.doPrivileged(Native Method) at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:182) at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:280) Caused by: com.sap.aii.mappingtool.tf7.IllegalInstanceException: Cannot create target element /ns1:Z_FUEL_VAL_UPDATE_PROCESS/PCFILE. Values missing in queue context. Target XSD requires a value for this element, but the target-field mapping does not create one. Check whether the XML instance is valid for the source XSD, and whether the target-field mapping fulfils the requirement of the target XSD at com.sap.aii.mappingtool.tf7.AMappingProgram.processNode(AMappingProgram.java:369) at com.sap.aii.mappingtool.tf7.AMappingProgram.processNode(AMappingProgram.java:411) at com.sap.aii.mappingtool.tf7.AMappingProgram.start(AMappingProgram.java:503) at com.sap.aii.mappingtool.tf7.Transformer.start(Transformer.java:134) at com.sap.aii.mappingtool.tf7.AMappingProgram.transform(AMappingProgram.java:635) at com.sap.aii.ib.server.mapping.execution.JavaMapping.executeStep(JavaMapping.java:92) … 39 more
I checked all the mapping seems to be identical to XI prod box.
Please let me know the resolution for this. We are in PI7.11
Thanks a lot in advance
Regards,
Mahesh
Hi Riyaz,
My problem is similar to what Neha Rai has posted.
After the first mapping , instead of this output:
Header – 1
Detail – 2
Weight – 3
Weight – 4
Detail – 5
Weight – 6
Weight – 7
Trailer
I am getting below:
Header – 1
Detail – 2
Detail – 3
Weight – 4
Weight – 5
Weight – 6
Weight – 7
Trailer
Quick tip…. more pictures and video clips in upcoming posts.
Big blocks of text hurt my eyes and I detest it, lol. Walls
of text hits for 900 damage…. haha. This joke never ever gets old.
Nice information though!
We’re a group of volunteers and opening a new scheme in our community. Your web site offered us with valuable information to work on. You’ve done a formidable job and our whole community will be
thankful to you.