1

I want to Convert a string value into decimal by using XSLT 2.0 to last two decimal places. I want to change the value of Country Code element to decimal.The input string length is fixed i.e 11.

Input XML:

<GetPersonResponse xmlns="http://www.example.com/xsd/Person_01_RequestResponse_001">
   <Person xsi:type="ns1:Person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ns2:PersonId xmlns:ns2="http://www.example.com/xsd/Person_01">4224</ns2:PersonId>
      <ns3:FirstName xmlns:ns3="http://www.example.com/xsd/Person_01">Omer</ns3:FirstName>
      <ns4:LastName xmlns:ns4="http://www.example.com/xsd/Person_01">Khalid</ns4:LastName>
      <ns5:FatherName xmlns:ns5="http://www.example.com/xsd/Person_01">Khalid</ns5:FatherName>
      <ns6:Religion xmlns:ns6="http://www.example.com/xsd/Person_01">Islam</ns6:Religion>
      <ns7:MotherTongue xmlns:ns7="http://www.example.com/xsd/Person_01">Urrdu</ns7:MotherTongue>
      <ns8:DateOfBirth xmlns:ns8="http://www.example.com/xsd/Person_01">1993-02-02</ns8:DateOfBirth>
      <ns9:Gender xmlns:ns9="http://www.example.com/xsd/Person_01" xsi:type="ns1:GenderType">Male</ns9:Gender>
      <ns10:CurrentAddress xmlns:ns10="http://www.example.com/xsd/Person_01" xsi:type="ns1:AddressDetail">
         <ns10:AddressDetailId>194</ns10:AddressDetailId>
         <ns10:StreetNo>5</ns10:StreetNo>
         <ns10:HouseNo>361</ns10:HouseNo>
         <ns10:Town>Johar</ns10:Town>
         <ns10:District>Lahore</ns10:District>
         <ns10:City>Lahore</ns10:City>
         <ns10:State>Punjab</ns10:State>
         <ns10:Country>Pakistan</ns10:Country>
         <ns10:Postal>54046543245</ns10:Postal>
      </ns10:CurrentAddress>
      <ns11:HomeAddress xmlns:ns11="http://www.example.com/xsd/Person_01" xsi:type="ns1:AddressDetail">
         <ns11:AddressDetailId>195</ns11:AddressDetailId>
         <ns11:StreetNo>5</ns11:StreetNo>
         <ns11:HouseNo>361</ns11:HouseNo>
         <ns11:Town>Johar</ns11:Town>
         <ns11:District>Lahore</ns11:District>
         <ns11:City>Lahore</ns11:City>
         <ns11:State>Punjab</ns11:State>
         <ns11:Country>Pakistan</ns11:Country>
         <ns11:Postal>54046543245</ns11:Postal>
      </ns11:HomeAddress>
      <ns12:Height xmlns:ns12="http://www.example.com/xsd/Person_01">6</ns12:Height>
      <ns13:Weight xmlns:ns13="http://www.example.com/xsd/Person_01">100</ns13:Weight>
      <ns14:CNIC xmlns:ns14="http://www.example.com/xsd/Person_01">35302</ns14:CNIC>
      <ns15:ContactInfo xmlns:ns15="http://www.example.com/xsd/Person_01" xsi:type="ns1:ContactDetail">
         <ns15:HomePhone>454545</ns15:HomePhone>
         <ns15:CellPhone>3343434</ns15:CellPhone>
         <ns15:WorkPlacePhone>34343434</ns15:WorkPlacePhone>
         <ns15:Email>omer@gmail.com</ns15:Email>
      </ns15:ContactInfo>
      <ns16:MaritalStatus xmlns:ns16="http://www.example.com/xsd/Person_01">Single</ns16:MaritalStatus>
      <ns17:Nationality xmlns:ns17="http://www.example.com/xsd/Person_01">Pakistani</ns17:Nationality>
   </Person>
   <ResponseCode>PERSON MODULE SUCCESS - 00</ResponseCode>
   <ResponseMessage>Data Fetched Successfully</ResponseMessage>
</GetPersonResponse>

Input XSLT:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.example.com/xsd/Person_01_RequestResponse_001"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:m0="http://www.example.com/xsd/Person_01"
xmlns:m="http://www.example.com/cdm/xsd/Person_01_RequestResponse_001"

>

<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//m0:CNIC"/>
</xsl:template>                     
<xsl:template match="//m0:CNIC">
    <m:GetPersonResponse>
<m:PersonId>
<m:NationalIdentityNumber>
<xsl:value-of select="//m0:CNIC"/>
</m:NationalIdentityNumber>

<m:CountryCode>
<xsl:attribute name="name"><xsl:value-of select="//m0:Postal"/></xsl:attribute>
            <xsl:attribute name="type">xs:decimal</xsl:attribute>
</m:CountryCode>
</m:PersonId>
    </m:GetPersonResponse>
</xsl:template>


</xsl:stylesheet>

Current XML Output:

<?xml version="1.0" encoding="UTF-8"?>
<m:GetPersonResponse xmlns:m="http://www.example.com/cdm/xsd/Person_01_RequestResponse_001" xmlns="http://www.example.com/xsd/Person_01_RequestResponse_001" xmlns:m0="http://www.example.com/xsd/Person_01" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <m:PersonId>
      <m:NationalIdentityNumber>35302</m:NationalIdentityNumber>
      <m:CountryCode name="54046543245" type="xs:decimal" />
   </m:PersonId>
</m:GetPersonResponse>

Required XML Output:

<?xml version="1.0" encoding="UTF-8"?>
<m:GetPersonResponse xmlns:m="http://www.example.com/cdm/xsd/Person_01_RequestResponse_001" xmlns="http://www.example.com/xsd/Person_01_RequestResponse_001" xmlns:m0="http://www.example.com/xsd/Person_01" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <m:PersonId>
      <m:NationalIdentityNumber>35302</m:NationalIdentityNumber>
      <m:CountryCode name="540465432.45" type="xs:decimal" />
   </m:PersonId>
</m:GetPersonResponse>

Note: There is also an approach in my mind that we can somehow convert our string into decimal and then divide it by 100. But how will it be done?

omer khalid
  • 855
  • 1
  • 12
  • 39

2 Answers2

2

In XSLT/XPath 2.0 you can convert to xs:decimal doing e.g. xs:decimal(m0:Postal) and divide using xs:decimal(m0:Postal) div 100 and format using format-number(xs:decimal(m0:Postal) div 100, '0.00'). You would not even need the explicit conversion to xs:decimal as with m0:Postal div 100 you would get a number any way that you could format: format-number(m0:Postal div 100, '0.00'). If you use XSLT 2.0 and want to use the explicit conversion with xs:decimal then you need to make sure the stylesheet declares xmlns:xs="http://www.w3.org/2001/XMLSchema".

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
1

As I said in the comments, you can do this purely by string manipulation and thus avoid the danger of losing leading/trailing zeros in the process of converting the string to a number:

<xsl:variable name="postal" select="//m0:Postal" />
<xsl:value-of select="concat(substring($postal, 1, 9), '.', substring($postal, 10, 2))"/>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51