cancel
Showing results for 
Search instead for 
Did you mean: 

SAP PI Graphical Mapping with UDF loops

Former Member
0 Kudos

Hi!

I Need Information on Java Source Code for Looping over XML nodes! I have the following node, which can be included up to 10 times. Now, i have to Loop over each entry and have to Change all of the fields (QUALF, TAGE, etc.) if a certain condition is fulfilled. How can i achieve this with a Java function? Where can i get Information on the necessary objects and source code examples?

Thanks and BR, EF

Accepted Solutions (1)

Accepted Solutions (1)

former_member184681
Active Contributor
0 Kudos

Hi Elmar,

You can always create a UDF that takes 4 input parameters (QUALF, TAGE, PRZNT, ZTERM_TXT) and manipulate those data inside your UDF, if that's your preference I think it depends much on the conditions you need to check.

Regards,

Greg

Former Member
0 Kudos

Hi!

My requirements are quite simple I want to check if RCVPRN has a certain value, e.g. 00000100. If this is the case, then each entry of E1EDK18 Needs to have its fields changed. E.g. if there are 3 entries under E1EDK18, each entry must Change (QUALF, TAGE, PRZNT, ZTERM_TXT) to e.g. 111,222,333 and 444. The Problem is, that UDF can of course only have 1 return Parameter. So it seems, that i have to build 4 functions, one for every field, but this seems strange ... ;( Is there a way to have 1 UDF function with Input Parameter RCVPRN which changes the four fields respectively?

BR, EF

former_member184681
Active Contributor
0 Kudos

For such a simple requirement, you don't even need UDF! Use standard mapping functions: equalsS to compare RCVPRN with your 0000000100 value, and if (with else) to produce the expected result value. Nothing simpler than that

If you're not too familiar with PI's graphical mapping concept, you might want to have a look at my blog:

Regards,

Greg

Former Member
0 Kudos

Hi!

OK, sounds reasonable. I  just thought about something like:

if(RCVPRN == '00000100'){

     foreach(element in E1EDK18){

          element.QUALF = 111;

          element.TAGE = 222;

          ......    

     }

}

Thanks in advance

BR, EF

former_member184681
Active Contributor
0 Kudos

Well, here is how I would personally implement it:

Then, same thing for other fields.

Regards,

Greg

Former Member
0 Kudos

Thank you, i implemented it like you said, with a graphical mapping But, there is one Problem left, now!

Here, you can see the mapping; the Problem is, that a test with 2 entries for E1EDK18 results in second entry, but without the 4 fields ... what is still wrong here?

former_member184681
Active Contributor
0 Kudos

Yeah, right. UseOneAsMany was missing, as below:

Regards,

Greg

Former Member
0 Kudos

Hi!

This was a really helpful answer! It works, so thank you!! Could you try to explain me, why the useOneAsMany function is necessary and how it works? The Standard Explanation is a bit fuzzy ...

BR, EF

former_member184681
Active Contributor
0 Kudos

Putting things simple: RCVPRN only occurs once in your IDoc, so the condition for IF was only checked once, and as a result, only one value was passed to the target field. UseOneAsMany "replicates" the source value (RCVPRN) as many times as the second argument occurs, so in your case it means "check the IF condition twice, for each E1EDK18 segment. The third argument is only for context changes formatting.

You just have to remember that PI always works on queues of values

Regards,

Greg

Answers (1)

Answers (1)

rhviana
Active Contributor
0 Kudos

Olá Hi Elmar,

My opnion is better use java mapping (parsing XML with DOM).

You can use the beggning of code below and insert your layout:

public void transform(TransformationInput tInp, TransformationOutput tOut)throws StreamTransformationException {

/*-----------------------------------------------------------

* Criando a variavel para capturar o TRACE dentro do SAP PI

*-----------------------------------------------------------*/

AbstractTrace absTraceLog = this.getTrace();

/*-------------------------------------------------------------------------

* Variavel String inptxml recebe o valore do TransformationInput (Stream)

*-------------------------------------------------------------------------*/

String inptxml = convertStreamToString(tInp.getInputPayload().getInputStream());

try {

DocumentBuilder domFactory = DocumentBuilderFactory.newInstance().newDocumentBuilder();

Transformer tf = TransformerFactory.newInstance().newTransformer();

Document doc = domFactory.parse(tInp.getInputPayload().getInputStream());

doc.getDocumentElement().normalize();

StringWriter sw = new StringWriter();

StreamResult result = new StreamResult(sw);

DOMSource source = new DOMSource(doc);

if (inptxml.contains("XMLNFe")) {

/*-------------------------------------------------------------------

* Criando uma lista X com todos os elementos do doc - Document doc

*------------------------------------------------------------------*/

NodeList x = doc.getDocumentElement().getElementsByTagName("*");

/*-----------------*

* Loop na lista   *

*-----------------*/

for (int i = 0; i < x.getLength(); i++) {

..........

NodeList x = doc.getDocumentElement().getElementsByTagName("*");

With this command above reads all XML notes and use (FOR OR WHILE) to control and insert what do you need.

This is part of java mapping code, you should complete it because if I share all my code will not be applied for you, because names and others stuffs.

Also check this link below:

http://wiki.scn.sap.com/wiki/display/XI/Beginners+guide+to+Java+mapping+using+DOM+parser+in+SAP+XI

Kind regards,

BR.

Ricardo Viana.