on 11-09-2006 12:44 AM
Hi Everyone,
I am brand new to XI and found out that GUI mappings create unnecessary complexity. I wonder if there is any way to simply them. Here is my problem:
Let's say I have the following source message:
<source>
<node> (cardinality: 0..9999)
<key>...</key>
<source_value1>...<source_value1> (cardinality: 0..1)
<source_value2>...<source_value2> (cardinality: 0..1)
<node>
</source>
My target message looks like this:
<target>
<target_value1>...</target_value1>
<target_value2>...</target_value2>
<target_value3>...</target_value3>
</target>
The mapping requirements are:
1. Map source_value1 to target_value1 when key = 'key1'
2. Map source_value1 to target_value2 when key = 'key2'
3. Map source_value2 to target_value3 when key = 'key3'
4. If source message contains nodes with keys other than key1, key2, key3, ignore them.
Pretty common requirements so far. Now let's start with GUI mapping. Obviously, I cannot use 'if..else' function in the GUI because it will only check the first occurrence of the <b>node</b> elements in the source message. So to meet the requirements, I have to create some custom functions.
At first, I decided to create a <u>context</u> function called findValue:
public void findValue(String[] key, String[] keyValue, String[] value, ResultList result, Container container){
for (int i = 0; i < key.length; i++) {
if (key<i>.equalsIgnoreCase(keyValue[0])) {
if (i < value.length) result.addValue(value<i>);
else result.addValue("");
return;
}
}
result.addValue("");
}
It is pretty simple to use this function. For example, to meet the 1st requirement, I pass <b>key</b> element to the first parameter, constant value <b>key1</b> to the second parameter, and <b>source_value1</b> to the third parameter. And I set the context on <b>key</b> and <b>source_value1</b> to <b>source</b> element.
This seems to solve the problem. Unfortunately, it is wrong because all the source_value elements are optional. For example, source_value1 element may not even exist when key = 'key2'. It means the array length of key[] and value[] are not necessarily the same. Thus, it will produce the wrong output.
It seems that the only way to solve this problem is to create an <u>queue</u> function rather than a context function. The modified version of findValue function looks like this now:
public void newFindValue(String[] key, String[] keyValue, String[] value, ResultList result, Container container) {
ArrayList valueList = new ArrayList();
for (int i = 0; i < value.length; i++) {
/* If the first value is CC or if there are two CCs in a row, produce an empty value in the value list. */
if (value<i>.equals(result.CC)) {
if (i == 0 || (i > 0 && value[i-1].equals(result.CC))) valueList.add("");
valueList.add(result.CC);
}
else {
valueList.add(value<i>);
}
}
if (key.length != valueList.size()) {
trace.addWarning("Mismatch key size and value size.");
}
int count = 0;
for (int i = 0; i < key.length; i++) {
if (key<i>.equalsIgnoreCase(keyValue[0])) {
if (count > 0) result.addContextChange();
result.addValue((String) valueList.get(i));
count++;
}
}
}
As you can see, the function is very complicated just to achieve a simple requirement. Also, I don't really like queue function because the performance will be poor.
Is there any better way to achieve such requirements without using custom queue functions? Any help is appreciated.
Thanks a lot!
Kenny Cheang
Hi Kenny,
It is very nice to hear from you to join in to XI Family.As per as my knowledge I felt that for your mapping requirement no need to go for Java Functions.
you can achieve this requirement by using Graphical Functions which XI has provided for us.
Note:Use Fixed Value under Conversion function.
1)Go to Function drop down list from the Message Mapping Editor
2)Select the Conversion from the selected drop down list and double click the conversion function and enter your key and value in the corresponding fields.
Ex:Key Value
123 Chandu
Please let me know for further clarifications
Thanks and Regards,
Chandu.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Chandu,
Thanks for your reply. But I don't see how FixedValue function can solve the problem. FixedValue converts one value to another. And you have to know all possible values in the source file. My requirement is not about value conversion.
> Hi Kenny,
>
> It is very nice to hear from you to join in to XI
> I Family.As per as my knowledge I felt that for your
> mapping requirement no need to go for Java
> Functions.
> you can achieve this requirement by using Graphical
> l Functions which XI has provided for us.
>
> Note:Use Fixed Value under Conversion function.
> 1)Go to Function drop down list from the Message
> Mapping Editor
> 2)Select the Conversion from the selected drop down
> list and double click the conversion function and
> enter your key and value in the corresponding
> fields.
>
> Ex:Key Value
> 123 Chandu
> Please let me know for further clarifications
>
> Thanks and Regards,
> Chandu.
if statements only checks the first occurrence of the <b>node</b> elements when the context is set to <b>node</b>.
For example, if the source message looks like this:
<source>
<node>
<key>key1</key>
<source_value1>value1</source_value1>
</node>
<node>
<key>key2</key>
<source_value1>value2</source_value1>
</node>
<node>
<key>key3</key>
<source_value2>value3</source_value2>
</node>
</source>
The if statement for testing key1 will be true. Thus, target_value1 will be populated. But the rest of if statements will never be true. Thus target_value2 and target_value3 will be blank.
Hi,
1. Map source_value1 to target_value1 when key = 'key1'
2. Map source_value1 to target_value2 when key = 'key2'
3. Map source_value2 to target_value3 when key = 'key3'
target_value1=ifWithoutElse(key="key1") then source_value1
target_value2=ifWithoutElse(key="key2") then source_value1
target_value1=ifWithoutElse(key="key3") then source_value2
and target top element createIf(FixedValue:key1="true",key2="true",key3="true",default="false"[default is not entry])
Regards,
Wojciech
> target_value2=ifWithoutElse(key="key2") then
> source_value1
<source>
<node>
<key>key2</key>
<source_value1>correct</source_value1>
</node>
<node>
<key>key1</key>
<source_value1>wrong</source_value1>
</node>
</source>
Take this one for example. When the context is set to node, this statement is evaluated twice.
First, the if statement is true, it returns source_value1 which is the value "correct".
Then the if statement is evaluated again and return false.
However, even when the second if statement failed, the context of source_value1 is changed. It is not the value "correct" any more. Now, it points to the value "wrong". So at the end, the value "wrong" is assigned to target_value2.
Hi,
Here is solution for such case:
1. Map source_value1 to target_value1 when key = 'key1'
2. Map source_value2 to target_value2 when key = 'key2'
3. Map source_value3 to target_value3 when key = 'key3'
a) duplicate target node (you need to have 3 target nodes), right click on the node and duplicate
b)
create user defined function rSUP (it will remove SUPPRESS)
for(int i=0;i<a.length;i++)
if(!a<i>.equals(ResultList.SUPPRESS))
result.addValue(a<i>);
c)
create your mapping similar to this one:
/ns0:target/target=rSUP(removeContexts(createIf(stringEquals(/ns0:source/node/key=, const([value=key1])))))
/ns0:target/target/target_value1=SplitByValue([type=Each value]/ns0:source/node/source_value1=)
/ns0:target/target[1]=rSUP(createIf(stringEquals(/ns0:source/node/key=, const([value=key2]))))
/ns0:target/target[1]/target_value2=SplitByValue([type=Each value]/ns0:source/node/source_value2=)
/ns0:target/target[2]=rSUP(removeContexts(createIf(stringEquals(/ns0:source/node/key=, const([value=key3])))))
/ns0:target/target[2]/target_value3=SplitByValue([type=Each value]/ns0:source/node/source_value3=)
key context is source
source_valueX context is source
Regards,
Wojciech
Hi Kenny,
Can you also give the cardinality of the Element "Key" in the source and also of all the target Elements.
Regards,
Abhy
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
hello
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 | |
10 | |
10 | |
10 | |
7 | |
6 | |
6 | |
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.