cancel
Showing results for 
Search instead for 
Did you mean: 

Order of source nodes

Former Member
0 Kudos

Hi,

I am trying to generate a sequence number basing on the order of appearance of the nodes on the source.

I have a source structure as:

<MESSAGE>

<MID>

<field1></field1>

<field2></field2>

</MID>

<KC>

<field3></field3>

<field4></field4>

</KC>

The target structure as:

<MESSAGE>

<MID>

<SeqNo></SeqNo>

<field1></field1>

<field2></field2>

</MID>

<KC>

<SeqNo></SeqNo>

<field3></field3>

<field4></field4>

</KC>

</MESSAGE>

The occurrence of MID and KC is 0...unbounded.

The sequence no. will be the index of node on the source in the order it appears.

If I have the source as MID, KC, MID. Then I should be able to generate sequence numbers for MID as 1 and 3 and for KC as 2 in thier target nodes respectively.

All help is greatly appreciated.

Thanks.

vj

Accepted Solutions (0)

Answers (5)

Answers (5)

Former Member
0 Kudos

Hi vijay,

I tried your case using JAVA Mapping. It was so easy and i got the ouput easily. If you are comfortable with java and parsing XML in java, then there is no issues, you can easily do your requirement using JAVA Mapping. If you are interested reply i will send the code for JAVA Mapping.

regards,

P.Venkat

Former Member
0 Kudos

Hi Vijay,

I tested your xslt in XI, and yes it is throwing an error even though it is working fine (after few changes) in Stylus Studio.

This could be the problem with the xml parser in XI. I have tested the same for XALAN parser it is working fine with that too.

So i have created one more xslt program to meet your requirement. Please find the code below. I have tested the same in IM too.

Also find the attached output for the corresponding input xml given above.

<b>XSL:</b>

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="DCOL">

<xsl:element name="DCOL">

<xsl:apply-templates/>

</xsl:element>

</xsl:template>

<xsl:template match="MESSAGE">

<xsl:copy>

<xsl:attribute name="status">

<xsl:value-of select="@status"/>

</xsl:attribute>

<xsl:attribute name="tentative">

<xsl:value-of select="@tentative"/>

</xsl:attribute>

<xsl:attribute name="type">

<xsl:value-of select="@type"/>

</xsl:attribute>

<xsl:for-each select="./*">

<xsl:variable name="ActualPosition" select="position()"/>

<xsl:variable name="IndexVar"><xsl:for-each select="../*[position() &lt; $ActualPosition]"><xsl:choose><xsl:when test="local-name()='MerchandiseItemDetail' or local-name()='AccountPayment' or local-name()='KatesCard' or local-name()='PostVoid' or local-name()='ReturnReceiptID' or local-name()='Discounts' or local-name()='ProratedDiscounts'">1</xsl:when></xsl:choose></xsl:for-each>1</xsl:variable>

<xsl:choose>

<xsl:when test="local-name()='MerchandiseItemDetail' or local-name()='AccountPayment' or local-name()='KatesCard' or local-name()='PostVoid' or local-name()='ReturnReceiptID' or local-name()='Discounts' or local-name()='ProratedDiscounts'">

<xsl:copy>

<xsl:element name="RetailSeqNo">

<xsl:value-of select="string-length($IndexVar)"/>

</xsl:element>

<xsl:copy-of select="*"/>

</xsl:copy>

</xsl:when>

<xsl:otherwise>

<xsl:copy-of select="."/>

</xsl:otherwise>

</xsl:choose>

</xsl:for-each>

</xsl:copy>

</xsl:template>

</xsl:stylesheet>

<b>Output:</b>

<?xml version="1.0" encoding="utf-8"?>

<DCOL>

<MESSAGE status="Complete" tentative="False" type="DCREQ">

<HEADER>

<MediaCount>0000</MediaCount>

<ModelID>9104</ModelID>

<StoreNumber>00001365</StoreNumber>

<SeqNumber>0001</SeqNumber>

<SystemID>0000</SystemID>

<TranNumber>00000201</TranNumber>

<TranType>86</TranType>

<TerminalNumber>0002</TerminalNumber>

<TermTypeCode>40</TermTypeCode>

<TranStatusCode>80</TranStatusCode>

</HEADER>

<StartSequence>

<DivisionNumber>0008</DivisionNumber>

<CashierID>0028</CashierID>

<SalesPersonID>0028</SalesPersonID>

<Date>20050627</Date>

<TransCompleteTime>00114520</TransCompleteTime>

<CashierSSN>000999999999</CashierSSN>

<SalesPersonSSN>000999999999</SalesPersonSSN>

<ReKeyFlag>0000</ReKeyFlag>

<TransStartTime>00114502</TransStartTime>

</StartSequence>

<AccountPayment>

<RetailSeqNo>1</RetailSeqNo>

<Modifier>2</Modifier>

<AccountNumberMSR>008707815230</AccountNumberMSR>

<TrackIIData>8707815230=000000000000</TrackIIData>

<PaymentAmount>-2500</PaymentAmount>

</AccountPayment>

<TenderSequence>

<Modifier>0</Modifier>

<TenderTypeCode>0001</TenderTypeCode>

<AmountTendered>2500</AmountTendered>

</TenderSequence>

<TenderSequence>

<Modifier>0</Modifier>

<TransactionTotal>99997500</TransactionTotal>

<RefundChangeDueAmount>0</RefundChangeDueAmount>

</TenderSequence>

<MerchandiseItemDetail>

<RetailSeqNo>2</RetailSeqNo>

<Modifier>0</Modifier>

<CompanyDesignation>BBW</CompanyDesignation>

<KeyedShortSKU>0051549853</KeyedShortSKU>

<FileShortSKU>0051549853</FileShortSKU>

<Division>0001</Division>

<Department>0051</Department>

<Class>0612</Class>

<Manufacturer>0000</Manufacturer>

<Style>00044450</Style>

<LongSKU>00100051006120000004445003719999000000</LongSKU>

<RegularFilePrice>720</RegularFilePrice>

<ExtendedFilePrice>720</ExtendedFilePrice>

<ItemProratedPrice>615</ItemProratedPrice>

</MerchandiseItemDetail>

<ProratedDiscounts>

<RetailSeqNo>3</RetailSeqNo>

<Modifier>0</Modifier>

<ProrationType>0012</ProrationType>

<PromoCode>01500101</PromoCode>

<CompanyDesignation>BBW</CompanyDesignation>

<ProrationPercent>00145833</ProrationPercent>

<ProrationAmount>-105</ProrationAmount>

</ProratedDiscounts>

<MerchandiseItemDetail>

<RetailSeqNo>4</RetailSeqNo>

<Modifier>0</Modifier>

<CompanyDesignation>BBW</CompanyDesignation>

<KeyedShortSKU>0047941614</KeyedShortSKU>

<FileShortSKU>0047941614</FileShortSKU>

<Division>0001</Division>

<Department>0066</Department>

<Class>0987</Class>

<Manufacturer>0000</Manufacturer>

<Style>00011408</Style>

<LongSKU>00100066009870000001140805959999000000</LongSKU>

<RegularFilePrice>800</RegularFilePrice>

<ExtendedFilePrice>800</ExtendedFilePrice>

<ItemProratedPrice>800</ItemProratedPrice>

</MerchandiseItemDetail>

</MESSAGE>

</DCOL>

<b>Note:</b>Please do not make any indentation for the xsl line starting with <b><xsl:variable name="IndexVar"></b> this might insert extra characters and change the sequence number.

Regards,

KNS Kumar.

Former Member
0 Kudos

Kumar,

Two thumbs up...there seems to be no way of changing the points I have previously awarded you. I really appreciate your time on my issue.You have been a great help in the past week.

I will probably see you around.

Thanks again,

vijay

Former Member
0 Kudos

Venkat,

I have got the solution from Kumar by using XSL. But I will be interested to look into other solutions too. I am also in the process of exploring solutions to this kind, through ABAP mapping and JAVA mapping.

could you also please provide me sample code?.

You can also send it to my email account at vponnavolu@gmail.com.

Thanks again,

vijay

Former Member
0 Kudos

Hi,

You can try developing a module to parse the incoming XML file and get the correct sequence.

Change the source structure as

<MESSAGE>

<MID>

<field1></field1>

<field2></field2>

<SeqNo></SeqNo>

</MID>

<KC>

<field3></field3>

<field4></field4>

<SeqNo></SeqNo>

</KC>

and add the SeqNo tag to the source xml in the module.

Method to get the sequence number is indexOf().Parse through all the subelements of MESSAGE and for each sub element check and add the seqNo tag as

int seqNo = element.getParent().indexOf(element)

element.addElement("SeqNo").addText(seqNo);

Call this as the first module in your sender communication channel.

Hope this helps.

Regards,

Uma

Former Member
0 Kudos

Hi Vinay,

I think this can be done by using function. You can try as below..

MID - index - splitByValue - SeqNo

Similarly for the other node.

Regards

Vishal

Former Member
0 Kudos

Hi Vijay,

While defining your source structure, you might have given as

MID Occurane(0, Unbounded)

KC Occurane(0, Unbounded)

Thus the XML parser in the XI assumes that the nodes MID nad KC will come in the specified sequence i.e all the occurance of MID will come first and then KC.

Even if your source XML comes as (you specified) MID , KC, MID, this will be interpreted as MID,MID,KC. Thus the order of XML nodes is lost. So this can not be bdone in graphical mapping.

Instead you can use XSLT mmaping which serves your requirement. PLease fidn the XSL code given below.

<b><?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">

<xsl:for-each select="./*">

<xsl:copy>

<xsl:for-each select="./*">

<xsl:copy>

<xsl:element name="SeqNo">

<xsl:value-of select="position()"/>

</xsl:element>

<xsl:for-each select="./*">

<xsl:copy-of select="."/>

</xsl:for-each>

</xsl:copy>

</xsl:for-each>

</xsl:copy>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet></b>

Regards,

KNS Kumar.

Former Member
0 Kudos

Vishal,

I already tried this, MID nodes are being grouped. So I am getting a 1 and 2 for sequence number of MID and 3 for KC.

What i need is a 1 and 3 for MID and 2 for KC.

Thanks,

vijay

Former Member
0 Kudos

Kumar,

Thanks for the response, your answer put me in a track where I was almost done. But the problem is that the xsl which works in XMl SPY does not work in the Interface Mapping.

The error I get is:

<b>Transformer exception occurred when executing XSLT genSeqNo (http://abc.com, b8f12d30-2c45-11da-90af-ef160a892024, -1)</b>

The error is caused by the below xsl code fragment:

<xsl:template match="MID | KC">
<xsl:copy>
<xsl:element name="RetailSeqNo">
<xsl:number count="./MID | ./KC"/>
</xsl:element>
<xsl:copy-of select="*">
</xsl:copy-of>
</xsl:copy>
</xsl:template>

If either of MID or KC does not exist in the source xml then the mapping program fails in XI it however does not fail in XML SPY. It fials when executing the count function.

Any help is appreciated.

Thanks,

vijay

Former Member
0 Kudos

Hi Vijay,

I tried to analyze the xsl code which you have pasted, but i could not get why exactly you are using the statement <b><xsl:number count="./MID | ./KC"/></b>.

I would like put forward my understanding of the code so that it can add more value.

The template block you defined will get executed every when it finds a node MID or KC but in the <xsl:number statement you are referring to./MID| ./KC this will look for a child node from current node having MID or KC pattern which does not exist. Thus at the end of the processing it will not generate any node.

It would be more help full if you can also paste the test data.

Also I would suggest you to use the above code which i have code, as it is independent of any node names, thus it can be applied to scenario of this kind irrespective of node names. I have tested that code in Interface Mapping with inputs you have given i.e. having structure MID KC MID...

Regards

KNS Kumar.

Former Member
0 Kudos

Kumar,

I am pasting a testfile and code which works in XML SPY but does not work in IF of IR. The source xml will be little different than I had

initially described in the start of this thread.

The only requirement foe this mapping is that the <b>RetailSeqNo</b> element is created only for those nodes mentioned in the <xsl:number>

element in XSL. You will see the output when you run the test file against the xsl I have provided.

I appreciate all your help and time spent on my issue.

<b>Source XML:</b>

<DCOL>
<MESSAGE type="DCREQ" status="Complete" tentative="False">
<HEADER>
<MediaCount>0000</MediaCount>
<ModelID>9104</ModelID>
<StoreNumber>00001365</StoreNumber>
<SeqNumber>0001</SeqNumber>
<SystemID>0000</SystemID>
 <TranNumber>00000201</TranNumber>
<TranType>86</TranType>
<TerminalNumber>0002</TerminalNumber>
<TermTypeCode>40</TermTypeCode>
<TranStatusCode>80</TranStatusCode>
</HEADER>
<StartSequence>
<DivisionNumber>0008</DivisionNumber>
<CashierID>0028</CashierID>
<SalesPersonID>0028</SalesPersonID>
<Date>20050627</Date>
<TransCompleteTime>00114520</TransCompleteTime>
<CashierSSN>000999999999</CashierSSN>
<SalesPersonSSN>000999999999</SalesPersonSSN>
<ReKeyFlag>0000</ReKeyFlag>
<TransStartTime>00114502</TransStartTime>
</StartSequence>
<AccountPayment>
<Modifier>2</Modifier>
<AccountNumberMSR>008707815230</AccountNumberMSR>
<TrackIIData>8707815230=000000000000</TrackIIData>
<PaymentAmount>-2500</PaymentAmount>
</AccountPayment>
<TenderSequence>
<Modifier>0</Modifier>
<TenderTypeCode>0001</TenderTypeCode>
<AmountTendered>2500</AmountTendered>
</TenderSequence>
<TenderSequence>
<Modifier>0</Modifier>
<TransactionTotal>99997500</TransactionTotal>
<RefundChangeDueAmount>0</RefundChangeDueAmount>
</TenderSequence>
<MerchandiseItemDetail>
<Modifier>0</Modifier>
<CompanyDesignation>BBW</CompanyDesignation>
<KeyedShortSKU>0051549853</KeyedShortSKU>
<FileShortSKU>0051549853</FileShortSKU>
<Division>0001</Division>
<Department>0051</Department>
<Class>0612</Class>
<Manufacturer>0000</Manufacturer>
<Style>00044450</Style>
<LongSKU>00100051006120000004445003719999000000</LongSKU>
<RegularFilePrice>720</RegularFilePrice>
<ExtendedFilePrice>720</ExtendedFilePrice>
<ItemProratedPrice>615</ItemProratedPrice>
</MerchandiseItemDetail>
<ProratedDiscounts>
<Modifier>0</Modifier>
<ProrationType>0012</ProrationType>
<PromoCode>01500101</PromoCode>
<CompanyDesignation>BBW</CompanyDesignation>
<ProrationPercent>00145833</ProrationPercent>
<ProrationAmount>-105</ProrationAmount>
</ProratedDiscounts>
<MerchandiseItemDetail>
<Modifier>0</Modifier>
<CompanyDesignation>BBW</CompanyDesignation>
<KeyedShortSKU>0047941614</KeyedShortSKU>
<FileShortSKU>0047941614</FileShortSKU>
<Division>0001</Division>
<Department>0066</Department>
<Class>0987</Class>
<Manufacturer>0000</Manufacturer>
<Style>00011408</Style>
<LongSKU>00100066009870000001140805959999000000</LongSKU>
<RegularFilePrice>800</RegularFilePrice>
<ExtendedFilePrice>800</ExtendedFilePrice>
<ItemProratedPrice>800</ItemProratedPrice>
</MerchandiseItemDetail>
</MESSAGE>
</DCOL>

<b>XSL that works in XMLM SPY:</b>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="DCOL">
<xsl:element name="DCOL">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>

<xsl:template match="MESSAGE">
<xsl:copy>
<xsl:attribute name="status"><xsl:value-of select="@status"/></xsl:attribute>
<xsl:attribute name="tentative"><xsl:value-of select="@tentative"/></xsl:attribute>
<xsl:attribute name="type"><xsl:value-of select="@type"/></xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
	
<xsl:template match="HEADER">
<xsl:copy-of select=".">
</xsl:copy-of>
</xsl:template>
	
<xsl:template match="StartSequence">
<xsl:copy-of select=".">
</xsl:copy-of>
</xsl:template>
	
<xsl:template match="MerchandiseItemDetail | KatesCard | PostVoid | AccountPayment | ReturnReceiptID | Discounts | ProratedDiscounts">
<xsl:copy>
<xsl:element name="RetailSeqNo">
<xsl:number count="./MerchandiseItemDetail  | ./KatesCard | ./AccountPayment | ./ReturnReceiptID | ./Discounts | ./ProratedDiscounts"/>
</xsl:element>
<xsl:copy-of select="*">
</xsl:copy-of>
</xsl:copy>
</xsl:template>
	

<xsl:template match ="*">
<xsl:copy-of select=".">
</xsl:copy-of>
</xsl:template>
	
</xsl:stylesheet>

Thank you,

vijay

Former Member
0 Kudos

Hi,

I think this can be done easily using JAVA mapping.

I dont think user defined advanced function may solve the problem. Let me know if this is possible.

regards

P.Venkat

Former Member
0 Kudos

Hi

Use advanced userdefined functions and pass the two nodes (MID,KC) as the input parameters to the function.

hope this works.

regards,

datta