on 01-30-2006 2:16 AM
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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() < $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.
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
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
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.
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi
Use advanced userdefined functions and pass the two nodes (MID,KC) as the input parameters to the function.
hope this works.
regards,
datta
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
93 | |
10 | |
10 | |
9 | |
9 | |
7 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.