0

I have an XML elements which needs to be transformed using XSLT to a different form. I have posted the request and response xml below. I am new to XSLT and need help in transforming the request to response format.

Request :

<p:ReservationRequest xmlns:p="http://sample.request.com/">
      <!--Exactly 1 occurrence-->
      <p:Reservation>
         <p:tktReservationGUID>13579</p:tktReservationGUID>
         <p:tktState>CA</p:tktState>
         <p:LocationId>1357</p:LocationId>
      </p:Reservation>
   </p:ReservationRequest>

Response:

  <tem:SendReservation xmlns:tem="http://tempuri.org/">
     <!--Optional:-->
     <tem:ProviderGuid xmlns:tem="http://tempuri.org/">1111</tem:ProviderGuid>
     <!--Optional:-->
     <tem:Username xmlns:tem="http://tempuri.org/">usertext</tem:Username>
     <!--Optional:-->
     <tem:Password xmlns:tem="http://tempuri.org/">passtext</tem:Password>
     <!--Optional:-->
     <tem:Data><![CDATA[<DATA> <Reservation>

     <tktReservationGUID>54321</tktReservationGUID>
     <tktState>CA</tktState>
     <LocationId>1357</LocationId>
  </Reservation> </DATA>]]></tem:Data>
  </tem:SendReservation>

I need to strip off the namespaces off the request elements and append them using CDATA in the response under "tem:DATA" after appending another master element "DATA" to the request elements.

I really appreciate any help in this regarding to transform the following request to the posted response using XSLT.

Regards, Rudraksh

1
  • Can you use XSLT 3.0 with Saxon 9.6? Or which XSLT version with which XSLT processor do you target? Commented Oct 30, 2014 at 8:46

2 Answers 2

2

Assuming XSLT 3.0 and Saxon 9.6 you can make use of the serialize function to convert a transformed temporary tree to markup:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:p="http://sample.request.com/"
  xmlns:tem="http://tempuri.org/"
  exclude-result-prefixes="p tem"
  version="3.0">

<xsl:output indent="yes" cdata-section-elements="tem:Data" omit-xml-declaration="yes"/>

<xsl:template match="/">
  <tem:SendReservation xmlns:tem="http://tempuri.org/">
     <!--Optional:-->
     <tem:ProviderGuid xmlns:tem="http://tempuri.org/">1111</tem:ProviderGuid>
     <!--Optional:-->
     <tem:Username xmlns:tem="http://tempuri.org/">usertext</tem:Username>
     <!--Optional:-->
     <tem:Password xmlns:tem="http://tempuri.org/">passtext</tem:Password>
     <!--Optional:-->
     <tem:Data>
       <xsl:variable name="data">
         <DATA>
           <xsl:apply-templates select="p:ReservationRequest"/>
         </DATA>
       </xsl:variable>
       <xsl:variable name="ser-params">
          <output:serialization-parameters
                 xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
            <output:indent value="yes"/>
            <output:version value="1.0"/>
            <output:method value="xml"/>
            <output:omit-xml-declaration value="yes"/>
          </output:serialization-parameters>
       </xsl:variable>
       <xsl:value-of select="serialize($data/*, $ser-params/*)"/>
     </tem:Data>
   </tem:SendReservation>
</xsl:template>

<xsl:template match="p:*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

That way the result is

<tem:SendReservation xmlns:tem="http://tempuri.org/">
   <tem:ProviderGuid>1111</tem:ProviderGuid>
   <tem:Username>usertext</tem:Username>
   <tem:Password>passtext</tem:Password>
   <tem:Data><![CDATA[<DATA>
   <ReservationRequest>

      <Reservation>
         <tktReservationGUID>13579</tktReservationGUID>
         <tktState>CA</tktState>
         <LocationId>1357</LocationId>
      </Reservation>
   </ReservationRequest>
</DATA>]]></tem:Data>
</tem:SendReservation>

If you need to do it with XSLT 1.0 then here is a sample making use of a serializer implemented in pure XSLT 1.0 and the exsl:node-set function:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:p="http://sample.request.com/"
  xmlns:tem="http://tempuri.org/"
  xmlns:exsl="http://exslt.org/common"
  exclude-result-prefixes="p tem exsl"
  version="1.0">

<xsl:import href="http://lenzconsulting.com/xml-to-string/xml-to-string.xsl"/>

<xsl:output indent="yes" cdata-section-elements="tem:Data" omit-xml-declaration="yes"/>

<xsl:template match="/">
  <tem:SendReservation xmlns:tem="http://tempuri.org/">
     <!--Optional:-->
     <tem:ProviderGuid xmlns:tem="http://tempuri.org/">1111</tem:ProviderGuid>
     <!--Optional:-->
     <tem:Username xmlns:tem="http://tempuri.org/">usertext</tem:Username>
     <!--Optional:-->
     <tem:Password xmlns:tem="http://tempuri.org/">passtext</tem:Password>
     <!--Optional:-->
     <tem:Data>
       <xsl:variable name="data">
         <DATA>
           <xsl:apply-templates select="p:ReservationRequest"/>
         </DATA>
       </xsl:variable>
       <xsl:apply-templates select="exsl:node-set($data)/*" mode="xml-to-string"/>
     </tem:Data>
   </tem:SendReservation>
</xsl:template>

<xsl:template match="p:*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

6 Comments

Martin, Thanks for your solution. However,this option is not supported in our XSLT engine. We are still using xsl 1.0 as part of our engine. Is there any solution which can be accomplished using xsl 1.0 ?
Either check whether your XSLT 1.0 processor provides or allows you to implement an extension function to serialize a tree or integrate a pure XSLT 1.0 solution like lenzconsulting.com/xml-to-string in your code.
@Rudraksh, I have added an XSLT 1.0 sample making use of the library module xml-to-string I have linked to in my earlier comment.
I tried that option too. However my editor is not using that module. I am still trying to make this one work. I really appreciate your faster turnaround.
Well you can download the stylesheet module and use it locally if your editor does not load it over HTTP.
|
1

I was able to change the input request a little bit to resemble closely to my response. I have posted my new request below along with the XSLT used to transform it.

New Request:

<p:ReservationRequest xmlns:p="http://sample.request.com/">
  <p:DATA>
      <!--Exactly 1 occurrence-->
      <p:Reservation>
         <p:tktReservationGUID>13579</p:tktReservationGUID>
         <p:tktState>CA</p:tktState>
         <p:LocationId>1357</p:LocationId>
      </p:Reservation>
  </p:DATA>
</p:ReservationRequest>

New XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tem="http://tempuri.org/" xmlns:p="http://sample.request.com/" exclude-result-prefixes="p tem" version="1.0">
      <xsl:output indent="yes" cdata-section-elements="tem:Data"/>
      <xsl:template match="/">
         <tem:SendReservation>
            <!--Optional:-->
            <tem:ProviderGuid>1111</tem:ProviderGuid>
            <!--Optional:-->
            <tem:Username>usertest</tem:Username>
            <!--Optional:-->
            <tem:Password>passtest</tem:Password>
            <!--Optional:-->
            <tem:Data>
               <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
               <xsl:apply-templates select="/p:ReservationRequest/p:DATA"></xsl:apply-templates>
               <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
            </tem:Data>
         </tem:SendReservation>
      </xsl:template>
      <xsl:template match="*">
         <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@*|node()"></xsl:apply-templates>
         </xsl:element>
      </xsl:template>
      <xsl:template match="@*">
         <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."></xsl:value-of>
         </xsl:attribute>
      </xsl:template>
   </xsl:stylesheet>

Response:

<tem:SendReservation xmlns:tem="http://tempuri.org/">
   <tem:ProviderGuid>1111</tem:ProviderGuid>
   <tem:Username>usertest</tem:Username>
   <tem:Password>passtest</tem:Password>
   <tem:Data><![CDATA[<DATA>
      <Reservation>
         <tktReservationGUID>13579</tktReservationGUID>
         <tktState>CA</tktState>
         <LocationId>1357</LocationId>
      </Reservation>
</DATA>]]></tem:Data>
</tem:SendReservation>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.