on 11-09-2004 12:30 PM
Hi all,
I use the XI Mapping tool and have the following source document structure:
<...>
<E1EDP01>
<POSEX>10</POSEX>
<E1EDP02>
<QUALF>001</QUALF>
<...>
</E1EDP02>
<E1EDP02>
<QUALF>002</QUALF>
<ZEILE>000010</ZEILE>
<...>
</E1EDP02>
<E1EDP02>
<QUALF>016</QUALF>
<ZEILE>000020</ZEILE>
<...>
</E1EDP02>
<...>
</E1EDP01>
<E1EDP01>
<POSEX>20</POSEX>
<...>
</E1EDP01>
<E1EDP01>
<POSEX>30</POSEX>
<...>
</E1EDP01>
<...>
and want to map it to the following target structure:
<...>
<item>
<ITM_NUMBER>10</ITM_NUMBER
<PO_ITEM>000010</PO_ITEM>
</item>
<item>
<ITM_NUMBER>20</ITM_NUMBER
<...>
</item>
<item>
<ITM_NUMBER>30</ITM_NUMBER
<...>
</item>
<...>
where every <item> corresponds to <E1EDP01> and the <PO_ITEM> corresponds to the <ZEILE> where <QUALF>='002'.
I tried the following java user function:
public void getQualifiedValue(String[] a, String[] b, String[] c, ResultList result, Container container){
int j = 0;
for (int i = 0; i < a.length; i++)
{
if (a<i>.equals(ResultList.CC))
{
j++;
continue;
}
if (!c[j].equals(ResultList.CC))
{
if (a<i>.equals(b[0]))
{
result.addValue(c[j]);
return;
}
j++;
}
}
}
to get the context switches right, because the <ZEILE> element is not contained in every <E1EDP02> context.
Therefore I checked 'Cache complete queue' and set the context of the input parameters <QUALF> and <ZEILE> to <E1EDP02>.
This function works for the first <item> element, but the next <item> elements do not have any <PO_ITEM> element.
Could any one please help me with this?
Thanks,
Hans
This problem should easily be solved with the equalsS and normal boolean functions of the graphical mapping tool.
Use equalsS to check if E1EDP02-QUALIF is 002 if so use the value of E1EDP02-ZEILE. Just make sure to set the context of the E1EDP02-QUALIF and ZEILE to E1EDP01.
Regards Johan
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Hans-Jürgen,
We had the same problem. The main problem with the XI graphical mapper is that it is a serial/SAX parser. So no relationships between fields and structures are maintained. You can build user defined java functions to solve this problem, but for these kind mappings we switched to XSLT mappings, they don't have relationship problems.
Cheers,
Frank Bakermans
Hi Frank,
thank you for your answer. You are the first to say that you experienced the same problem. I even tried the SAP helpdesk but they only referred me to read the mapping manual...
How is the XSLT mapping performance compared to the message mapping?
Do I have to include the XSLT mapping into a jar file and then import it in the Integration Builder?
Cheers,
Hans
Hi Hans,
I was part of one of the XI 3.0 Ramp-up projects and we forwarded this problem to SAP. SAP has no real answer to this, only that this problem is very difficult to solve in their Graphical Mapper and that solving the problem with user defined java functions is at the moment the only way.
The perfomance of XSLT mappings are less, but hardly noticeable with rather small mappings. Yes you include the XSLT mapping into a Jar or Zip file and then import in the integration Builder. Be aware that the mapping has to have the extension .XSL instead of .XSLT, otherwise the mapping can't be found (undocumented feature).
Good luck,
Frank
Hans,
This in not a problem. It is the way the SAX parser works. It only loads a context at a time. This is good for memory consumption and performance.
You need to read up on the context queue in the sap documentation http://help.sap.com/saphelp_nw04/helpdata/en/84/4afc51f65c4e4fabfbbbd25f548ab7/frameset.htm
Basically either use explicit references or the "removeContext" function. You have context changes between each SAP IDoc segment. SAP XI mapping therefore does not load the different context. You need to tell it to ignore the context changes.
This does work, I have got it working.
If you use the removeContexts http://help.sap.com/saphelp_nw04/helpdata/en/84/4afc51f65c4e4fabfbbbd25f548ab7/frameset.htm you get reference all the E1EDP01 and E1EDPxx at the same time.
Regards,
Simon
Hi Simon,
I read the docu on the context issue at least a dozen times and also worked with the different context functions.
But the problem mentioned above happens, when some elements do not exits (so they are not empty, but they do not exits at all).
In the queue there is now indication whatever, that there should be a null value or anything like this. The SAX parser has a queue of three values for the QUALF element, but a queue of only two values for the ZEILE element and those references get out of sync.
Even if I try all combinations of "removeContext" and "splitByValue" I do not get the requested results.
I tried user functions to review the queues (since in XI 2.0 I cannot view queues at test runtime) but did not get it working.
I think I switch to XSLT mappings, because in these cases they are much more readable than message mappings, where I have to use ten or more items in the graphical editor just to get a simple if statement working.
Regards,
Hans
Hi Hans,
I got an example running by just using the standard functions in the graphical mapping. The example looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<ns3:MT_Context_Test xmlns:ns3="urn:sca.com:emailsystem:test">
<P01>
<ITEM>10</ITEM>
<P02>
<QUALF>001</QUALF>
</P02>
<P02>
<QUALF>002</QUALF>
<ZEILE>000010</ZEILE>
</P02>
<P02>
<QUALF>016</QUALF>
<ZEILE>000020</ZEILE>
</P02>
</P01>
<P01>
<ITEM>20</ITEM>
<P02>
<QUALF>002</QUALF>
<ZEILE>000020</ZEILE>
</P02>
<P02>
<QUALF>016</QUALF>
<ZEILE>000025</ZEILE>
</P02>
</P01>
</ns3:MT_Context_Test>
And the corresponding result is this:
<?xml version="1.0" encoding="UTF-8"?>
<ns3:MT_Context_Test2 xmlns:ns3="urn:sca.com:emailsystem:test">
<ITEM>
<ITEM_NO>10</ITEM_NO>
<ITEM_PO>000020</ITEM_PO>
</ITEM>
<ITEM>
<ITEM_NO>20</ITEM_NO>
<ITEM_PO>000020</ITEM_PO>
</ITEM>
</ns3:MT_Context_Test2>
If you like to see the graphical mapping, I could export all needed objects and send tmen to you!
Best regards
/Michael
Hi Hans,
I didn't make any errors in my typing but you were right. It was not 100% correct. I made some changes and now it's working as you need it:
<?xml version="1.0" encoding="UTF-8"?>
<ns3:MT_Context_Test2 xmlns:ns3="urn:sca.com:emailsystem:test">
<ITEM>
<ITEM_NO>10</ITEM_NO>
<ITEM_PO>000010</ITEM_PO>
</ITEM>
<ITEM>
<ITEM_NO>20</ITEM_NO>
<ITEM_PO>000020</ITEM_PO>
</ITEM>
</ns3:MT_Context_Test2>
This is a very good example of how to manage context problems by only using the graphical maspping tool! I'll keep it as well for my own...
Best regards
/Michael
Hi Kerry,
I used two user defined functions for that:
1.) getSynchronizedField
public String getSynchronizedField(String qualifierField, String qualifierValue, String valueField, Container container){
if (qualifierField.equals(qualifierValue))
return valueField;
else
return ResultList.SUPPRESS;
}
This function is value-based. Parameter qualifierField is a field which exists alyways in the context (e. g. QUALF). Parameter qualifierValue is the constant value to be compared (e. g. 001). Parameter valueField is the field sometimes missing in the context (e. g. ZEILE). The output is a queue with the same structure as of parameter qualifierField, where not existing values of valueField have the SUPPRESS value.
2.) splitContext
public void splitContext(String[] splitByField,String[] valueField,ResultList result,Container container){ int j = 0;
for (int i = 0; i < splitByField.length; i++)
{
if (splitByField<i>.equals(ResultList.CC))
result.addValue(ResultList.CC);
else
{
if (!valueField[j].equals(ResultList.SUPPRESS))
result.addValue(valueField[j]);
j++;
}
}
This function is on queue level. Parameter splitByField is a field which defines the context changes (e. g. QUALF with context E1EDP01). Parameter valueField is the result of the previous function with contexts (removeContext between these two). The result is a queue with the correct values (ZEILE or SUPPRESS) in the same context as splitByField.
Example:
Structure in:
<E1EDP01>
<E1EDP02>
<QUALF>001</QUALF>
</E1EDP02>
<E1EDP02>
<QUALF>002</QUALF>
<ZEILE>000010</ZEILE>
</E1EDP02>
</E1EDP01>
<E1EDP01>
<E1EDP02>
<QUALF>001</QUALF>
<ZEILE>4</ZEILE>
</E1EDP02>
<E1EDP02>
<QUALF>002</QUALF>
<ZEILE>000020</ZEILE>
</E1EDP02>
</E1EDP01>
First function:
QUALF =>
Constant[001] => getSynchronizedField
ZEILE =>
Result is queue:
SUPPRESS
--
000010
--
4
--
000020
Then RemoveContext and 2. function:
QUALF[Context E1EDP01] =>
previous result =>splitContext
Result is:
SUPPRESS
--
4
Regards,
Hans
Hi Hans,
if you run XI 3.0 you can solve your problems very easy by using the graphical mapping tool. There you have a lot of functions regarding context- and node handling. We did a similar mapping for IDoc PROACT and it works pretty fine!
/Michael
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
84 | |
24 | |
12 | |
9 | |
7 | |
6 | |
5 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.