on 01-16-2014 7:37 PM
Hi Experts
I have a xml generated in PI from a file as below
<?xml version="1.0" encoding="utf-8"?>
<ns:ABCD xmlns:ns="urn:XYZ">
<document_hdr>
<d1>
<d2>
</document_hdr>
<document_vendor>
<v1>
<v2>
</document_vendor>
<document_gl>
<gl1>
<gl2>
</document_gl>
<document_gl>
<gl1>
<gl2>
</document_gl>
<document_hdr>
<d1>
<d2>
</document_hdr>
<document_vendor>
<v1>
<v2>
</document_vendor>
<document_gl>
<gl1>
<gl2>
</document_gl>
I want to assign a serial number for each node from top to bottom; where the number changes when <document_hdr> node starts
could anybody help me with the xslt
First xslt
It will assign a serial number to each group
<?xml version="1.0" encoding="utf-8"?>
<ns:ABCD xmlns:ns="urn:XYZ">
<document_hdr>
<d1>
<d2>
<ser>1
</document_hdr>
<document_vendor>
<v1>
<v2>
<ser>1
</document_vendor>
<document_gl>
<gl1>
<gl2>
<ser>1
</document_gl>
<document_gl>
<gl1>
<gl2>
<ser>1
</document_gl>
<document_hdr>
<ser>2
<d1>
<d2>
</document_hdr>
<document_vendor>
<v1>
<v2>
<ser>2
</document_vendor>
<document_gl>
<gl1>
<gl2>
<ser>2
</document_gl>
Hello Girish Joshi,
When I use this XML
<?xml version="1.0" encoding="UTF-8"?>
<ns:ABCD xmlns:ns="urn:XYZ">
<document_hdr>
<d1/>
<d2/>
</document_hdr>
<document_vendor>
<v1/>
<v2/>
</document_vendor>
<document_gl>
<gl1/>
<gl2/>
</document_gl>
<document_gl>
<gl1/>
<gl2/>
</document_gl>
<document_hdr>
<d1/>
<d2/>
</document_hdr>
<document_vendor>
<v1/>
<v2/>
</document_vendor>
<document_gl>
<gl1/>
<gl2/>
</document_gl>
</ns:ABCD>
and I apply this XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//document_hdr">
<xsl:variable name="index">
<xsl:number/>
</xsl:variable>
<xsl:element name="document_hdr">
<counter>
<xsl:value-of select="$index"/>
</counter>
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I get this output:
<?xml version="1.0" encoding="UTF-8"?>
<ns:ABCD xmlns:ns="urn:XYZ">
<document_hdr>
<counter>1</counter>
<d1/>
<d2/>
</document_hdr>
<document_vendor>
<v1/>
<v2/>
</document_vendor>
<document_gl>
<gl1/>
<gl2/>
</document_gl>
<document_gl>
<gl1/>
<gl2/>
</document_gl>
<document_hdr>
<counter>2</counter>
<d1/>
<d2/>
</document_hdr>
<document_vendor>
<v1/>
<v2/>
</document_vendor>
<document_gl>
<gl1/>
<gl2/>
</document_gl>
</ns:ABCD>
Is that what you need?
Best regarsd,
Peter
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Harish
Please note that in the source xml the header, vendor, GL nodes do not have any common field to group them together
My source XML is a 2 level xml with no parent - child relationship.
I want to force a parent child relationship either by XSLT or graphical mapping as [er below psuedo-logic.
First transformation will populate a serial number element in each of the header, vendor, gl nodes thus grouping them together.
Second transformation.
Insert all vendor & gl nodes found till the next header node as children of the current header node.
Please see the picture attached.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Girish,
as per above screenshot TEST_HEADER_01 is node/element contains the header information. try the below logic to get the level number
TEST_HEADER_01--> remove context --> index --> split by value --> map to target
If you don't get the desired result then please give the display queue screenshot.
regards,
Harish
Hi Girish - AFAIK - If all your segments are on same level then i don't think removecontext/ any other function would be helpful. You can go for java mapping / make use of below approach if that helps..(retrun as xml)
Based on my understanding of your strcture i tried something(was intrested in your requirement so )
Mapping : Map your source message type(use return as xml) to target message type.
result:
UDF:
String[] input = var1.split("</Test_header_01>");
String output="";
int counter=1;
for (int i=0;i<input.length;i++)
{
output = output+input[i]+"<serial>"+counter+"</serial>"+"</Test_header_01>";
counter++;
}
return output;
first replace string input : <?xml version="1.0" encoding="UTF-8"?>
second replace string input : <ns0:Messagetypename xmlns:ns0="namespace">
Hi Girish,
you can use the <param> element for this, and add 1 to it for every node you encounter.
<param name="counter" select="$counter + 1"/>
kr,
Peter
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Harish
Unfortunately this does not work - this is because the nodes in my source xml follow each other serially.
The header node gets the serial number correctly. But the other nodes between 2 header nodes do not get the serial number properly.
Regards
Girish
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Girish,
you can achieve this in graphical map. try the below logic.
Header --> index --> map to target
Apply the logic where you want the number.
regards,
Harish
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
81 | |
10 | |
10 | |
9 | |
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.