I have an integration object with this XML representation:
<root>
<request code="123" title="Test">
<user name="Chuck Bartowski" email="-" />
<data d1="aaa" d2="bbb" d3="ccc" />
<attachments>
<attachment name="text.txt" size="50" />
<attachment name="image.png" size="385" />
</attachments>
</request>
</root>
And I need to merge some of the nodes (integration components) into one, to convert the XML into something like this:
<root>
<request code="123" title="Test" userName="Chuck Bartowski" userEmail="-"
data1="aaa" data2="bbb" data3="ccc" />
<attachments>
<attachment name="text.txt" size="50" />
<attachment name="image.png" size="385" />
</attachments>
</request>
</root>
I'm trying to achieve this using Siebel 7.8 data mappings (EAI Data Transformation Engine). So, I have created an integration object map, with the following integration component maps:
NAME SOURCE IC TARGET IC
r1 request -> request
r2 user -> request
r3 data -> request
att attachment -> attachment
Unfortunately, it's not doing what I was expecting. Instead, it outputs this:
<root>
<request code="123" title="Test">
<attachments>...</attachments>
</request>
<request userName="Chuck Bartowski" userEmail="-">
<attachments>...</attachments>
</request>
<request data1="aaa" data2="bbb" data3="ccc">
<attachments>...</attachments>
</request>
</root>
I know it's possible to map a single source component into multiple targets, but, can the opposite be done? Can I merge many sources into a single target?
So far, I've tried setting the Parent Component Map Name field to r1
, in both r2
and r3
, but it only earned me a nice SBL-EAI-04008 error: Integration component type 'request' is not a valid child type for component type 'request'.
Am I missing some configuration step, or is this just impossible to do using only the data mapping engine? I'm calling it from a server script, so if nothing else works, I could just adapt the property set there after the mapping finishes.
I found the answer in the Siebel bookshelf. Yes, it can be done, but not how I was trying to do it:
You may want to address fields in components other than the source component. This is because your target component may depend on more than one component in the source object. In such cases, you cannot use different component maps with different source components, and the same target component, because each component map creates a different instance of the target component. Data Mapping Engine expressions allow you to use the dot notation to address fields, other than the source component, in source integration object components —for example,
[Component Name.Field Name]
.Addressing fields in other components is legal only if the cardinality of the component is less than or equal to one relative to the source component —that is, only if the component can be uniquely identified from the context of the source component without using any qualifiers other than the component name.
So, the key is to create only one component mapping for each target, and then include field mappings from the other sources. In my example, I would have:
NAME SOURCE IC TARGET IC
req request -> request
att attachment -> attachment
And inside req
, the following field mappings:
SOURCE TARGET
[code] -> code
[title] -> title
[user.name] -> userName
[user.email] -> userEmail
[data.d1] -> data1
...