cancel
Showing results for 
Search instead for 
Did you mean: 

mapping question - how to remove empty recordsets from output XML?

Former Member
0 Kudos

Hello everyone!

I have a mapping problem I hope you can help me out with.

Here is an example of the source message:

<IDOC>

. <HEAD>

. </HEAD>

. <DET>

. . <Node>

. . . <nodeA>001</nodeA>

. . . <nodeB>OA</nodeB>

. . </Node>

. . <Node>

. . . <nodeB>OB</nodeB>

. . </Node>

. . <Node>

. . . <nodeA>002</nodeA>

. . . <nodeB>OC</nodeB>

. . </Node>

. </DET>

</IDOC>

After testing the above XML in the message mapping, here's what my target looks like:

<FILE>

. . <Rec>

. . . <nA>001</nA>

. . . <nB>OA</nB>

. . </Rec>

. . <Rec>

. . . <nB>

. . . <nA>

. . </Rec>

. . <Rec>

. . . <nA>002</nA>

. . . <nB>OC</nB>

. . </Rec>

</FILE>

"Node" in the "source" message is mapped to "Rec" in my "target" message.

"Node=" -


> "Rec"

You may notice the the "Rec" in the second entry has empty fields. The reason this is so is because I put an "IF" condition in field "nA" and field "nB" that checks whether "nodeA" in the "source" exists/has a value, and if it doesn't, empty values should be given.

Here's my problem, I need the XML output to be clean. All empty Recs should be removed from the Output XML so that it resembles the one below:

<FILE>

. . <Rec>

. . . <nA>001</nA>

. . . <nB>OA</nB>

. . </Rec>

. . <Rec>

. . . <nA>002</nA>

. . . <nB>OC</nB>

. . </Rec>

</FILE>

I've tried several ways to get this done to no avail. Would anyone be able to help me out? I would really, really appreciate it!

Warm regards,

Glenn

Accepted Solutions (0)

Answers (5)

Answers (5)

Former Member
0 Kudos

Hello everyone,

I solved this problem by writing a UDF that checks the necessary conditions and returns a NULL value if they were not met.

For example:

if(a!=null){

return b;

}

return null;

According to SAP Note: 1090369, a bug in the standard IF functions causes inconsistent behaviour in the mapping program.

Thanks for all your replies!

Glenn

Former Member
0 Kudos

Hi,

Check with this mapping.

NodeA>Booleanfunction(or)>NodeB>exists>createif-->Rec

NodeA-->na

NodeB-->nb

Former Member
0 Kudos

I don't think that's the requirement! to check condition on both "NodeA" and "NodeB".

Hi Glenn,

Could you please share the Display Queue after the 'exists' function and of "NodeA" as well (with default context?

Regards,

Suddha

Former Member
0 Kudos

Hello,

Here's how the Display Queue looks like from the "CreateIF"

Default Context:

0 [false] [suppress]

1 [false] [suppress]

2 [false] [suppress]

3 [true] []

4 [false] [suppress]

5 [true] []

6 [false] [suppress]

7 [false] [suppress]

8 [false] [suppress]

9 [true] []

10 [false] [suppress]

11 [false] [suppress]

12 [false] [suppress]

13 [true] []

14 [false] [suppress]

15 [false] [suppress]

16 [false] [suppress]

17 [true] []

18 [false] [suppress]

19 [false] [suppress]

20 [false] [suppress]

21 [true] []

CreateIF Context up one notch:

0 [false] [suppress]

1 [true] []

2 [true] []

3 [true] []

4 [true] []

5 [true] []

6 [true] []

7 [true] []

8 [false] [suppress]

9 [false] [suppress]

10 [false] [suppress]

11 [false] [suppress]

Here's how the Display Queue looks like from the "NodeA"

SUPPRESS [false]

SUPPRESS [false]

[0000000292] [false]

[0000000292] [true]

[0000000252] [false]

[0000000252] [true]

SUPPRESS [false]

[0000000078] [false]

[0000000078] [false]

SUPPRESS [true]

[0000000109] [false]

[0000000109] [false]

SUPPRESS [false]

[0000000292] [true]

[0000000292] [false]

SUPPRESS [false]

[0000000076] [false]

[0000000076] [true]

SUPPRESS [false]

[0000000292] [false]

[0000000292] [false]

SUPPRESS [true]

SUPPRESS [false]

NodeA context one notch up:

SUPPRESS [false]

[0000000292] [true]

[0000000252] [true]

[0000000078] [true]

[0000000109] [true]

[0000000292] [true]

[0000000076] [true]

[0000000292] [true]

[0000000074] [true]

[0000000077] [true]

[0000000081] [true]

[0000000292] [true]

[0000000252] [true]

[0000000081] [true]

[0000000081] [false]

SUPPRESS

Hope that helps you help me!

Glenn

Former Member
0 Kudos

Hi Glenn,

Hope this helps.................

you wrote,

"I put an "IF" condition in field "nA" and field "nB" that checks whether "nodeA" in the "source" exists/has a value, and if it doesn't, empty values should be given."

What I understand from this is, if "nodeA" doesn't exist both "nA" and "nb" are kept empty (the same condition for both the target nodes) - which means "Rec" segment in target message doesn't need to occur at all if "NodeA" doesn't exist in the corresponding "Node" segment of source. Then why not use the condition in the parent level?

In this case it is best to use the condition "If 'NodeA' exists" then "create" target segment 'REC'.

Instead of mapping directly with the source segment as:

"Node=" -


> "Rec"

Map as:

"NodeA" -


> exists -


> createIf -


> "Rec"

note: Set the context of the source segment "NodeA" to the level of "DET".

While mapping the child fields "nA" and "nB" use default context for the source fields and then use the functions 'removeContext' and 'splitByValue (for each value)' in sequence at the end, as example:

"NodeA"(default context) --->exists -


> if

"NodeB"(default context) -


> then -


> removeContext -


> splitByValue (for each value) -


>nB

Let us know if it works!

regards,

Suddha

Former Member
0 Kudos

Hi Mario,

The occurence of NodeA and NodeB are both 0...1

Hi Suddhasatta,

You are right in your assessment, the solution does not seem to want to work though.

I tried your suggestion: "NodeA" -


> exists -


> createIf -


> "Rec"

I even played around with the context levels of "NodeA", but the results either give me all the Recordsets (even the empty ones) or none at all.

I am truly lost..... Please keep your suggestions coming, though...

Former Member
0 Kudos

There is a question,

Do you want to omit the occurances for "NodeA" = "" (empty string) or only for "NodeA doesn't exist at all".

If you are trying with empty value in "NodeA", then we certainly need some change in the logic.

Could you please clarify the test data instance you are using?

Regards,

Suddha

Former Member
0 Kudos

Hi Suddhasatta,

NodeA sometimes does not appear at all in the source XML, that is the condition I'm working with so I guess the 'exists' function is appropriate.

Weird thing though, when I tried not using the 'exists' function, but instead gave a specific value, for example,

NodeA -- equalS='OC' --> CreateIF --> Rec

It gives me the exact result I'm looking for!

Really strange it doesn't want to work with 'exists'

Regards,

Glenn

former_member187563
Contributor
0 Kudos

HI,

Just change the occurrence to 0:unbounded for receiver

regards,

ujjwal kumar

Former Member
0 Kudos

Hi Ujjwal and Mario,

Thanks for your replies!

Sadly, none of the two solutions worked. The occurence level for the 'Rec' node in the target structure is 0...Unbounded.

I tried using the "exists" combined with the "if" function:

IF 'nodeA' EXISTS='true' Then Node -


> Rec

I also tried it with the 'createIF'

IF 'nodeA' EXISTS='true' Then Node + CREATEIF -


> Rec

Any more ideas how to make it work?

Warm regards,

Glenn

Former Member
0 Kudos

Hi Glenn,

what is the occurence of

?

Regards Mario

Edited by: Mario Müller on Aug 5, 2008 8:18 AM

Former Member
0 Kudos

Try,

"NodeA" -


> exists -


> createIf -


> "Rec"

with the context of "NodeA" set to "Det".

This should work.

Regards,

Suddha

Former Member
0 Kudos

Hi Glenn,

if you already tries with

exists

I asume the occurence of the target fields is 1:unbounded?

So the field will always be generated due to it minOccurs = 1

Regards Mario