cancel
Showing results for 
Search instead for 
Did you mean: 

Mapping context problem

Former Member
0 Kudos

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

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

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

Former Member
0 Kudos

The normal equalsS and boolean functions do not work correctly in this case, as there are missing ZEILE elements. Therefore the queue gets out of sync so that I get the ZEILE from an other E1EDP02 then the QUALF which meets the condition.

Regards

Hans

Former Member
0 Kudos

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

Former Member
0 Kudos

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

Former Member
0 Kudos

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

Former Member
0 Kudos

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

Former Member
0 Kudos

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

Former Member
0 Kudos

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

Former Member
0 Kudos

Hi Michael,

if you did not make any typing errors in your post you just got the same problem as I did:

> <ITEM>

> <ITEM_NO>10</ITEM_NO>

> <ITEM_PO>000020</ITEM_PO>

> </ITEM>

The ITEM_PO is "000020" which is not the value of QUALF=002, but of QUALF=016...

Regards,

Hans

Former Member
0 Kudos

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

Former Member
0 Kudos

I need to do exactly the same mapping for INVOIC and ZEILE is not present in the first E1EDP02 segment (QUALF = 001), so I am not matching up the correct values of ZEILE when QUALF = 002 or QUALF = 016.

What was the fix using the graphical mapping tool?

Thanks,

Kerry Notestine

Former Member
0 Kudos

Hello, I am a bit late here, but perhaps this blog will be of some help to you, it demonstrates the functions that XI provides for UDF's that allow you to manipulate context's in your target structure:

/people/harrison.holland5/blog/2006/12/08/mapping-context-changes-in-xi

Former Member
0 Kudos

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

Former Member
0 Kudos

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