XSLT tranform a SOAP message

Viewed 40

Already searched for an answer here, but couldn't find any suitable solution...!

I'm trying to write a XSLT tranformation, starting from a SOAP response message, to be transformed to a XML message (the XML tags will not be the same).

Here is my input SOAP message :

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <CatalogPriceResponseParams xmlns="http://theurl.com">
        <ArrayOfOutputCatalogItems>
            <ItemID>003332</ItemID>
            <ShipFromPartyWarehouseLocationID>901</ShipFromPartyWarehouseLocationID>
            <Quantity>20.0</Quantity>
            <UnitCode>PCE</UnitCode>
            <UnitPriceAmount>104.9</UnitPriceAmount>
            <UnitPricePerQuantity>1.0</UnitPricePerQuantity>
            <UnitPricePerQuantityUOM>EA</UnitPricePerQuantityUOM>
            <PricingAmountUnitPretaxAmount>104.9</PricingAmountUnitPretaxAmount>
        </ArrayOfOutputCatalogItems>
        <ArrayOfOutputCatalogItems>
            <ItemID>003333</ItemID>
            <ShipFromPartyWarehouseLocationID>901</ShipFromPartyWarehouseLocationID>
            <Quantity>1.0</Quantity>
            <UnitCode>PCE</UnitCode>
            <UnitPriceAmount>100.9</UnitPriceAmount>
            <UnitPricePerQuantity>1.0</UnitPricePerQuantity>
            <UnitPricePerQuantityUOM>EA</UnitPricePerQuantityUOM>
            <PricingAmountUnitPretaxAmount>100.9</PricingAmountUnitPretaxAmount>
        </ArrayOfOutputCatalogItems>
    </CatalogPriceResponseParams>
    </soap:Body>
</soap:Envelope>

the desired output is :

<TradeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xsi:noNamespaceSchemaLocation="genericResponse.xsd">
   <getPrices>
      <errorCode>0</errorCode>
      <currency>EUR</currency>
      <articleList>
         <article>
            <articleId>003332</articleId>
            <icon>2</icon>
            <priceList>
               <price>
                  <price>104.9</price>
               </price>
            </priceList>
         </article>
         <article>
            <articleId>003333</articleId>
            <icon>2</icon>
            <priceList>
               <price>
                  <price>100.9</price>
               </price>
            </priceList>
         </article>
      </articleList>
   </getPrices>
</TradeResponse>

I already started to write a XSLT transformation but this doesn"t give the expected result:

<xsl:stylesheet version="1.0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="soap:*">
        <xsl:apply-templates select="*"/>
    </xsl:template>
    <xsl:template match="/">
        <TradeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="genericResponse.xsd">
            <getPrices>
                <errorCode>
                    <xsl:value-of select="'0'"/>
                </errorCode>
                <currency>
                    <xsl:value-of select="'EUR'"/>
                </currency>
                <articleList>
                    <xsl:for-each select=".*/CatalogPriceResponseParams/ArrayOfOutputCatalogItems">
                        <article>
                            <articleId>
                                <xsl:value-of select="./ItemID"/>
                            </articleId>
                            <icon>
                                <xsl:value-of select="'2'"/>
                            </icon>
                            <priceList>
                                <price>
                                    <price>
                                        <xsl:value-of select="./UnitPriceAmount"/>
                                    </price>
                                </price>
                            </priceList>
                        </article>
                    </xsl:for-each>
                </articleList>
            </getPrices>
        </TradeResponse>
    </xsl:template>
</xsl:stylesheet>

I hacve issue with the for-each instructions and I'm not able to address the XPathes I need.

Any help would be appreciated !

Many Thanks, David.

1 Answers

As I mentioned in the comments, the main issue here is the default namespace declared in your XSLT. Once you fix that, and remove the unnecessary verbosity, you should be able to do with:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns0="http://theurl.com"
exclude-result-prefixes="soap ns0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/soap:Envelope">
    <TradeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="genericResponse.xsd">
        <getPrices>
            <errorCode>0</errorCode>
            <currency>EUR</currency>
            <articleList>
                <xsl:for-each select="soap:Body/ns0:CatalogPriceResponseParams/ns0:ArrayOfOutputCatalogItems">
                    <article>
                        <articleId>
                            <xsl:value-of select="ns0:ItemID"/>
                        </articleId>
                        <icon>2</icon>
                        <priceList>
                            <price>
                                <price>
                                    <xsl:value-of select="ns0:UnitPriceAmount"/>
                                </price>
                            </price>
                        </priceList>
                    </article>
                </xsl:for-each>
            </articleList>
        </getPrices>
    </TradeResponse>
</xsl:template>

</xsl:stylesheet>
Related