Transform an XML by grouping the fields - xslt

My knowledge to XSLT is limited but always eager to learn. I am currently working on a template that requires to transform the XML input. I've been trying to group the InvoiceNum fields and not getting anywhere.
I am getting an error: Envision.Utilities.XsltEngine-Object reference not set to an instance of an object.
Here's the input XML for reference:
<?xml version='1.0' ?>
<Request>
<Information>
<ImageID>987456321</ImageID>
<Contract>123456789</Contract>
<Lastname>MICKEYMOUSE</Lastname>
</Information>
<Document>
<InvoiceNum>123456823</InvoiceNum>
<Reference>AD20985224</Reference>
<InvoiceNum>100000123</InvoiceNum>
<Reference>AS20101387</Reference>
<InvoiceNum>858511825</InvoiceNum>
<Reference>GF96844</Reference>
<InvoiceNum>885154145</InvoiceNum>
<Reference>FGFD2018</Reference>
<InvoiceNum>25241111</InvoiceNum>
<Reference>SD88888</Reference>
<InvoiceNum>8571414</InvoiceNum>
<Reference>DF864841254</Reference>
</Document>
</Request>
Here's my XSLT format for reference:
What am I missing? Is there better way to format the XSLT template I have currently below? Any help is greatly appreciated.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="cols" select="3" />
<xsl:template match="Request">
<table border="1">
<xsl:apply-templates select="InvoiceNum[position() mod $cols = 1]"/>
</table>
</xsl:template>
<xsl:template match="Document">
<xsl:variable name="group" select=". | following-sibling::InvoiceNum
[position() < $cols]" />
<xsl:for-each select="*">
<xsl:variable name="i" select="position()" />
<Invoice>
<InvoiceNumber>
<xsl:value-of select="InvoiceNum()"/>
</InvoiceNumber>
<xsl:for-each select="$group">
<xsl:value-of select="*[$i]"/>
</xsl:for-each>
</Invoice>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Here's the XML output I'd like to have:
<InvCase>
<Invoices>
<InvoicemNumber>InvoiceNum1</InvoicemNumber>
<InvoicemNumber>InvoiceNum2</InvoicemNumber>
<InvoicemNumber>InvoiceNum3</InvoicemNumber>
</Invoices>
</InvCase>

It looks like you are trying to group in the InvoiceNum into groups of 3. The first issue you have is that in your template matching Request you do this...
<xsl:apply-templates select="InvoiceNum[position() mod $cols = 1]"/>
But InvoiceNum is not a child of Request, and so that selects nothing. You probably need to do this...
Additionally, you have a template matching Document, but this probably needs to match InvoiceNum (Doing following-sibling::InvoiceNum would not return anything if you were matching Document as the InvoiceNum elements are children of Document not following siblings).
Try this XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="cols" select="3" />
<xsl:template match="Request">
<InvCases>
<xsl:apply-templates select="Document/InvoiceNum[position() mod $cols = 1]"/>
</InvCases>
</xsl:template>
<xsl:template match="InvoiceNum">
<xsl:variable name="group" select=". | following-sibling::InvoiceNum[position() < $cols]" />
<Invoice>
<xsl:for-each select="$group">
<InvoiceNumber>
<xsl:value-of select="."/>
</InvoiceNumber>
</xsl:for-each>
</Invoice>
</xsl:template>
</xsl:stylesheet>

Related

XSLT Transformation that add namespace prefix doesn't copy attributes

I have a requirement to add a namespace prefix to all my xml elements.
I have a working xslt for this but unfortunately it doesn't copy the attributes. What do I need to change to also copy these attributes.
This my code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:ns0="http://ns.hr-xml.org/2007-04-15" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="*">
<xsl:element name="ns0:{local-name()}">
<xsl:apply-templates select="*|node()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The input XML is this:
<HumanResource schemaLocation="http://ns.hr-xml.org/2007-04-15 ../HumanResource.xsd">
<HumanResourceId idOwner="StaffingCompany">
<IdValue>123COMP</IdValue>
</HumanResourceId>
<HumanResourceId idOwner="StaffingCustomer">
<IdValue>456CUST</IdValue>
<!--double hre-id, due fms wnr-code swap-->
</HumanResourceId>
<HumanResourceStatus status="x:Assigned"/>
<ReferenceInformation>
<StaffingSupplierId idOwner="StaffingCustomer">
<IdValue>105964</IdValue>
</StaffingSupplierId>
<StaffingCustomerId idOwner="StaffingCompany">
<IdValue>MIN0000612</IdValue>
</StaffingCustomerId>
<StaffingCustomerId idOwner="StaffingCustomer">
<IdValue>ELI</IdValue>
</StaffingCustomerId>
<StaffingSupplierOrgUnitId idOwner="StaffingCompany">
<IdValue>2606379</IdValue>
</StaffingSupplierOrgUnitId>
<StaffingCustomerOrgUnitId idOwner="StaffingCustomer">
<IdValue>ELI</IdValue>
</StaffingCustomerOrgUnitId>
</ReferenceInformation>
<ResourceInformation>
<PersonName>
<FormattedName>J</FormattedName>
<LegalName>C</LegalName>
<GivenName>J</GivenName>
<PreferredGivenName>J</PreferredGivenName>
<MiddleName>C.J.</MiddleName>
<FamilyName primary="true"></FamilyName>
</PersonName>
<EntityContactInfo>
<EntityName></EntityName>
<PersonName>
<FormattedName>Liesbeth Kramer</FormattedName>
</PersonName>
<ContactMethod>
<Telephone>
<FormattedNumber>070-3102150</FormattedNumber>
</Telephone>
</ContactMethod>
</EntityContactInfo>
<PostalAddress>
<CountryCode>NL</CountryCode>
<PostalCode></PostalCode>
<Municipality></Municipality>
<DeliveryAddress>
<AddressLine></AddressLine>
<StreetName></StreetName>
<BuildingNumber></BuildingNumber>
</DeliveryAddress>
</PostalAddress>
</ResourceInformation>
<Profile/>
<Preferences/>
<UserArea>
<ns2:HumanResourceAdditionalNL xmlns:ns2="http://ns.setu.nl/2008-01">
<ns2:BirthDate>1961-07-13</ns2:BirthDate>
<ns2:Sex>female</ns2:Sex>
</ns2:HumanResourceAdditionalNL>
</UserArea>
</HumanResource>
My result with my code looks like this:
<?xml version='1.0' ?>
<ns0:HumanResource xmlns:ns0="http://ns.hr-xml.org/2007-04-15">
<ns0:HumanResourceId>
<ns0:IdValue>123COMP</ns0:IdValue>
</ns0:HumanResourceId>
<ns0:HumanResourceId>
<ns0:IdValue>456CUST</ns0:IdValue>
</ns0:HumanResourceId>
<ns0:HumanResourceStatus/>
<ns0:ReferenceInformation>
As you can see, the ns0: is added ok but I lost the attributes.
You have lost the attributes because you have no code to select them. You currently do <xsl:apply-templates select="*|node()" />, but * select elements, and node() selects elements, text nodes, comments and processing instructions. You need to change it to this...
<xsl:apply-templates select="#*|node()" />
You would then need a separate template to match attributes and copy them.
<xsl:template match="#*">
<xsl:copy />
</xsl:template>
Try this XSLT
<xsl:stylesheet version="1.0" xmlns:ns0="http://ns.hr-xml.org/2007-04-15" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="*">
<xsl:element name="ns0:{local-name()}">
<xsl:apply-templates select="#*|node()" />
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:copy />
</xsl:template>
</xsl:stylesheet>
Alternatively, you could use xsl:copy-of to copy the attributes. Try this XSLT too
<xsl:stylesheet version="1.0" xmlns:ns0="http://ns.hr-xml.org/2007-04-15" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="*">
<xsl:element name="ns0:{local-name()}">
<xsl:copy-of select="#*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Note that <xsl:apply-templates /> is short-hand for <xsl:apply-templates select="node()" />

XSL to get values from nodes basing on the attribute value match

I am pretty much new to xsl.Currently facing a challenge in transforming the below sample xml to required output.
Sample XML:
<root>
<types>
<entity-type>
<field-type identifier="FieldType1" proxy-ref="TypeA">
<object-name>aclProxy</object-name>
<persistence-class-name>java.lang.Long</persistence-class-name>
</field-type>
<field-type identifier="FieldType2" proxy-ref="TypeB">
<object-name>aclName</object-name>
<persistence-class-name>java.lang.String</persistence-class-name>
</field-type>
</entity-type>
</types>
<custom>
<category identifier="parent" order="1">
<name>%category.parent</name>
</category>
<category identifier="texts" order="2">
<name>%category.Texts</name>
</category>
<field identifier="ArticleID" category-ref="parent" field-type-ref="FieldType1" proxy-entity-ref="ABC">
<name>%field.name</name>
<description>%field.Article.description</description>
</field>
<field identifier="ArticleName" category-ref="texts" field-type-ref="FieldType2" proxy-entity-ref="ABCD">
<name>%field.name.text</name>
<description>%field.Articletext.description</description>
</field>
</custom>
</root>
Output
<field identifier="ArticleID">
<name>%field.name</name>
<description>%field.Article.description</description>
<category-ref-name>%category.parent</category-ref-name>
<field-type-ref>Long</field-type-ref>
<proxy-entity-ref>TypeA</proxy-entity-ref>
</field>
<field identifier="ArticleName" >
<name>%field.name.text</name>
<description>%field.Articletext.description</description>
<category-ref-name>%category.Texts</category-ref-name>
<field-type-ref>String</field-type-ref>
<proxy-entity-ref>TypeB</proxy-entity-ref>
</field>
XSLT which I have been trying:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="category" match="category" use="#identifier" />
<xsl:key name="field" match="field" use="#category-ref" />
<xsl:apply-templates select="custom[not(key('field',category/#identifier))]"/>
<xsl:template match="/">
<xsl:text>something</xsl:text>
<xsl:value-of select="category/#identifier"/>
<xsl:apply-templates select="."/>
</xsl:template>
<xsl:template match="/">
<xsl:value-of select="field/#identifier"/>
<xsl:variable name="categoryparam" select="key('category', field/#category-ref)" />
<xsl:if test="$categoryparam">
<xsl:apply-templates select="$categoryparam"/>
<xsl:text>something</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Basically the output should have only field(s) in it referring to the attributes and get the node values.
Any help is much appreciated.
Thanks in advance.
Let us start off with these 2 keys:
<xsl:key name="kCategory" match="category" use="#identifier" />
<xsl:key name="kFieldID" match="field-type" use="#identifier" />
you will need the values in category and field-type nodes later.
This template:
<xsl:template match="/">
<xsl:apply-templates select="root/custom/field"/>
</xsl:template>
will output the target field nodes
Having a template match with the field node to further manipuate the output:
<xsl:template match="field">
<xsl:copy>
<!-- copies the identifier attribute and all children -->
<xsl:copy-of select="#identifier|node()"/>
<category-ref-name>
<!-- gets the child name of the target category node
that matches the category-ref attribute -->
<xsl:value-of select="key('kCategory', #category-ref)/name"/>
</category-ref-name>
<field-type-ref>
<!-- gets the child persistence-class-name of the target
field-type node that matches the field-type-ref attribute,
with further substring manipulations -->
<xsl:value-of select="substring-after(key('kFieldID', #field-type-ref)/persistence-class-name, 'java.lang.')"/>
</field-type-ref>
<proxy-entity-ref>
<!-- gets the attribute proxy-ref of the target
field-type node that matches the field-type-ref
attribute -->
<xsl:value-of select="key('kFieldID', #field-type-ref)/#proxy-ref"/>
</proxy-entity-ref>
</xsl:copy>
</xsl:template>
The whole stylesheet is below:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kCategory" match="category" use="#identifier" />
<xsl:key name="kFieldID" match="field-type" use="#identifier" />
<xsl:template match="/">
<xsl:apply-templates select="root/custom/field"/>
</xsl:template>
<xsl:template match="field">
<xsl:copy>
<xsl:copy-of select="#identifier|node()"/>
<category-ref-name>
<xsl:value-of select="key('kCategory', #category-ref)/name"/>
</category-ref-name>
<field-type-ref>
<xsl:value-of select="substring-after(key('kFieldID', #field-type-ref)/persistence-class-name, 'java.lang.')"/>
</field-type-ref>
<proxy-entity-ref>
<xsl:value-of select="key('kFieldID', #field-type-ref)/#proxy-ref"/>
</proxy-entity-ref>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
See it in action (http://xsltfiddle.liberty-development.net/gWmuiJc).

Call templates with same match string in different context

I want to transform a source xml into a target xml where certain matches from the source xml are included in different context in the target xml. For example I have a source xml like:
<shiporder>
<shipto>orderperson1</shipto>
<shipto>orderperson1</shipto>
<city>London</city>
</shiporder>
On this source xml I apply the following stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:call-template name="root" />
</xsl:template>
<xsl:template name="root">
<root>
<xsl:apply-templates select="/shiporder"/>
<xsl:call-template name="Customer"/>
</root>
</xsl:template>
<xsl:template name="Customer">
<Customer>
<!--<xsl:apply-templates select="/shiporder"/>-->
</Customer>
</xsl:template>
<xsl:template match="/shiporder">
<xsl:apply-templates select="shipto"/>
</xsl:template>
<xsl:template match="/shiporder/shipto">
<Address>
<xsl:apply-templates select="text()"/>
</Address>
</xsl:template>
</xsl:stylesheet>
In the template of name Customer I like to apply a template like:
<xsl:template match="/shiporder">
<xsl:apply-templates select="city"/>
</xsl:template>
<xsl:template match="/shiporder/city">
<City>
<xsl:apply-templates select="text()"/>
</City>
</xsl:template>
But I already defined a template with match /shiporder. So I don't know how to design a stylesheet where both templates with the same match exists in their own context?
If you use mode, like #michael.hor257k suggested you can differentiate between two or more templates that match on the same element but with different results.
In your case that could end up looking like this:
<?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" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:call-template name="root" />
</xsl:template>
<xsl:template name="root">
<root>
<xsl:apply-templates select="/shiporder" mode="root"/>
<xsl:call-template name="Customer"/>
</root>
</xsl:template>
<xsl:template name="Customer">
<Customer>
<xsl:apply-templates select="/shiporder" mode="customer"/>
</Customer>
</xsl:template>
<xsl:template match="/shiporder" mode="root">
<xsl:apply-templates select="shipto"/>
</xsl:template>
<xsl:template match="/shiporder" mode="customer">
<xsl:apply-templates select="city"/>
</xsl:template>
<xsl:template match="shipto">
<Address>
<xsl:apply-templates select="text()"/>
</Address>
</xsl:template>
<xsl:template match="city">
<City>
<xsl:apply-templates select="text()"/>
</City>
</xsl:template>
</xsl:stylesheet>
Obviously all credits here go to Michael for pointing this out first.

Moving and renaming contents of an XML node

i am a newbie when it comes to XSLT translations, and have been searching with this question for a while, but did not find any answher to it. I have an XML file looking like this:
<item>
<code>I001</code>
<description>DEF</description>
<properties>
<line1>
<key>key 1</key>
<value>value 1</value>
</line1>
<line2>
<key>key 2</key>
<value>value 2</value>
</line2>
</properties>
</item>
The label-software that i need to process this data with does not cope with this kind of leveled xml, so i have to transform it to something like this
<?xml version="1.0" encoding="utf-8"?>
<item>
<code>I001</code>
<description>DEF</description>
<P1_key>key 1</P1_key>
<P1_value>value 1</P1_value>
<P2_key>key 1</P2_key>
<P2_value>value</P2_value>
</item>
So far i have come up with an xsl-file that looks like this:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<!-- Identity rule -->
<xsl:template match="node() | #*">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<!-- special rules ... -->
<xsl:template match="properties/line1/*">
<xsl:element name="P1_{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="properties/line2/*">
<xsl:element name="P2_{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
This does only partly what i need (renaming the elements), wit a result looking like this:
<?xml version="1.0" encoding="utf-8"?>
<item>
<code>I001</code>
<description>DEF</description>
<properties>
<line1>
<P1_key>key 1</P1_key>
<P1_value>value 1</P1_value>
</line1>
<line2>
<P2_key>key 1</P2_key>
<P2_value>value</P2_value>
</line2>
</properties>
</item>
What i now would like to now is how to move the renamed elements (P1_key, P1_value, P2_key, P2_value) to the level.
Any hints would be appreciated.
Thanks
How about:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/item">
<xsl:copy>
<xsl:copy-of select="code | description"/>
<xsl:for-each select="properties/*/key">
<xsl:element name="P{position()}_key">
<xsl:value-of select="."/>
</xsl:element>
<xsl:element name="P{position()}_value">
<xsl:value-of select="following-sibling::value[1]"/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Or perhaps:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/item">
<xsl:copy>
<xsl:copy-of select="code | description"/>
<xsl:for-each select="properties/*/key">
<xsl:variable name="line-num" select="substring-after(name(..), 'line')" />
<xsl:element name="P{$line-num}_key">
<xsl:value-of select="."/>
</xsl:element>
<xsl:element name="P{$line-num}_value">
<xsl:value-of select="following-sibling::value[1]"/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Of course, if there always will be exactly two lines, you could just spell it out:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/item">
<xsl:copy>
<xsl:copy-of select="code | description"/>
<P1_key>
<xsl:value-of select="properties/line1/key" />
</P1_key>
<P1_value>
<xsl:value-of select="properties/line1/value" />
</P1_value>
<P2_key>
<xsl:value-of select="properties/line2/key" />
</P2_key>
<P2_value>
<xsl:value-of select="properties/line2/value" />
</P2_value>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
BTW, your method could work too, if you add another template:
<xsl:template match="properties | line1 | line2">
<xsl:apply-templates />
</xsl:template>

how to control multiple tags not neccessary that to repeat again

here i m target a data with table of CTD_CTD_PKG_ID in my xslt but some tags were having data pretty same that type of tags we have to control not to repeat once more
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<Table>
<RECORD_TYPE_CODE>CTD</RECORD_TYPE_CODE>
<MSG_TYPE_CODE>O102</MSG_TYPE_CODE>
<CTD_SEQ_NUM>089938</CTD_SEQ_NUM>
<CTD_CTD_PKG_ID>345</CTD_CTD_PKG_ID>
<CTD_LANG_ID>E</CTD_LANG_ID>
</Table>
<Table>
<RECORD_TYPE_CODE>ITD</RECORD_TYPE_CODE>
<MSG_TYPE_CODE>O103</MSG_TYPE_CODE>
<CTD_SEQ_NUM>089939</CTD_SEQ_NUM>
<CTD_CTD_PKG_ID>345</CTD_CTD_PKG_ID>
<CTD_LANG_ID>E</CTD_LANG_ID>
</Table>
</NewDataSet>
i have written my xslt below
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" omit-xml-declaration="yes" />
<xsl:param name="PackageId" />
<xsl:template match="/">
<xsl:apply-templates select="NewDataSet/Table[CTD_CTD_PKG_ID ='345']"/>
</xsl:template>
<xsl:template match="NewDataSet/Table[CTD_CTD_PKG_ID ='345']">
<xsl:value-of select= "concat(':25:',./CTD_LANG_ID)"/>,<xsl:text/>
<xsl:if test ="./RECORD_TYPE_CODE" >
<xsl:if test=" position() > 1"></xsl:if>
<xsl:text/><xsl:value-of select= "concat(':20:',./RECORD_TYPE_CODE)" />,<xsl:text/>
</xsl:if>
<xsl:if test ="./MSG_TYPE_CODE" >
<xsl:if test=" position() > 1"></xsl:if>
<xsl:text/><xsl:value-of select= "concat(':21:',./MSG_TYPE_CODE)"/>,<xsl:text/>
</xsl:if>
<xsl:if test ="./CTD_SEQ_NUM" >
<xsl:if test=" position() > 1"></xsl:if>
<xsl:text/><xsl:value-of select= "concat(':22:',./CTD_SEQ_NUM)"/>,<xsl:text/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
current output for this above xslt
:25:E,:25:E,
Expected output=
:25:E,
If you are using such specific IDs, a simple way to do this would be to simply select the first TABLE with the matching ID using the position() function, like so
<xsl:apply-templates select="NewDataSet/Table[CTD_CTD_PKG_ID ='345'][position()=1]"/>
Note that, you can actually simplify the template match by just matching on Table if required. Here is the whole XSLT in this case
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
<xsl:param name="PackageId"/>
<xsl:template match="/">
<xsl:apply-templates select="NewDataSet/Table[CTD_CTD_PKG_ID ='345'][position()=1]"/>
</xsl:template>
<xsl:template match="Table">
<xsl:value-of select="concat(':25:',./CTD_LANG_ID)"/>,
<xsl:text/></xsl:template>
</xsl:stylesheet>
When applied on your input XML, the result is as follows:
:25:E,