kwitee
kwitee

Reputation: 163

XSLT transformation of SOAP response

I am trying to download and transform soap response from Magyar Nemzeti Bank. I managed to get the downloading part right, now I am having a problem with xslt transformation. I want to transform the message to xml so I can deserialize it.

The SOAP response:

<?xml version="1.0" encoding="utf-8" ?> 
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
   <GetCurrentExchangeRatesResponse xmlns="http://www.mnb.hu/webservices/">
     <GetCurrentExchangeRatesResult>
       <MNBCurrentExchangeRates>
         <Day date="2013-12-03">
           <Rate curr="AUD" unit="1">203,5</Rate>
           <Rate curr="BGN" unit="1">154,82</Rate>
           <Rate curr="BRL" unit="1">94,69</Rate>
           <Rate curr="CAD" unit="1">209,79</Rate>
           <Rate curr="CHF" unit="1">246,21</Rate>
           <Rate curr="CNY" unit="1">36,62</Rate>
           <Rate curr="CZK" unit="1">11,02</Rate>
           <Rate curr="DKK" unit="1">40,59</Rate>
           <Rate curr="EUR" unit="1">302,8</Rate>
           <Rate curr="GBP" unit="1">366,05</Rate>
           <Rate curr="HKD" unit="1">28,78</Rate>
           <Rate curr="HRK" unit="1">39,67</Rate>
           <Rate curr="IDR" unit="100">1,88</Rate>
           <Rate curr="ILS" unit="1">63,32</Rate>
           <Rate curr="INR" unit="1">3,58</Rate>
           <Rate curr="ISK" unit="1">1,87</Rate>
           <Rate curr="JPY" unit="100">217,08</Rate>
           <Rate curr="KRW" unit="100">21,04</Rate>
           <Rate curr="LTL" unit="1">87,71</Rate>
           <Rate curr="LVL" unit="1">430,68</Rate>
           <Rate curr="MXN" unit="1">16,89</Rate>
           <Rate curr="MYR" unit="1">69,33</Rate>
           <Rate curr="NOK" unit="1">36,46</Rate>
           <Rate curr="NZD" unit="1">183,65</Rate>
           <Rate curr="PHP" unit="1">5,1</Rate>
           <Rate curr="PLN" unit="1">72,03</Rate>
           <Rate curr="RON" unit="1">67,89</Rate>
           <Rate curr="RSD" unit="1">2,65</Rate>
           <Rate curr="RUB" unit="1">6,71</Rate>
           <Rate curr="SEK" unit="1">34,08</Rate>
           <Rate curr="SGD" unit="1">177,85</Rate>
           <Rate curr="THB" unit="1">6,93</Rate>
           <Rate curr="TRY" unit="1">109,6</Rate>
           <Rate curr="UAH" unit="1">27,14</Rate>
           <Rate curr="USD" unit="1">223,09</Rate>
           <Rate curr="ZAR" unit="1">21,59</Rate>
         </Day>
       </MNBCurrentExchangeRates>
     </GetCurrentExchangeRatesResult> 
   </GetCurrentExchangeRatesResponse>
  </soap:Body>
</soap:Envelope>

My XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://www.mnb.hu/webservices/">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" />
    <xsl:template match="/">
        <xsl:element name="list">           
            <xsl:value-of select="soap:Envelope/soap:Body/ws:GetCurrentExchangeRatesResponse/ws:GetCurrentExchangeRatesResult" /> 
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

This XSLT works as excpected, but I can´t get any deeper than that. Every time I am trying to get to the MNBCurrentExchangeRates element, select result is empty. (I tryied ws:MNBCurrentExchangeRates, *[local-name()='MNBCurrentExchangeRates'] and many other less realistic options)

If it helps, spec for this soap request states that content of GetCurrentExchangeRatesResult element is string:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetCurrentExchangeRatesResponse xmlns="http://www.mnb.hu/webservices/">
      <GetCurrentExchangeRatesResult>string</GetCurrentExchangeRatesResult>
    </GetCurrentExchangeRatesResponse>
  </soap:Body>
</soap:Envelope>

Is there a way to get Day and Rate elements and select them?

Thanks, kwitee

EDIT: I tried both user3016153's and Mathias Müller's answers and none of them worked for me so let me change the question:

Why this XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://www.mnb.hu/webservices/">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" />
    <xsl:template match="/">
        <xsl:element name="list">           
            <xsl:value-of select="//ws:GetCurrentExchangeRatesResult" /> 
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

is working and this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://www.mnb.hu/webservices/">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" />
    <xsl:template match="/">
        <xsl:element name="list">           
            <xsl:value-of select="//ws:MNBCurrentExchangeRates" /> 
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

is not?

Mathias Müller's answer created this result (xml encoding is somehow broken and date acces doesn't work):

<?xml version="1.0" encoding="utf-16"?>&lt;MNBCurrentExchangeRates&gt;&lt;Day date="2013-12-03"&gt;&lt;Rate curr="AUD" unit="1"&gt;203,5&lt;/Rate&gt;&lt;Rate curr="BGN" unit="1"&gt;154,82&lt;/Rate&gt;&lt;Rate curr="BRL" unit="1"&gt;94,69&lt;/Rate&gt;&lt;Rate curr="CAD" unit="1"&gt;209,79&lt;/Rate&gt;&lt;Rate curr="CHF" unit="1"&gt;246,21&lt;/Rate&gt;&lt;Rate curr="CNY" unit="1"&gt;36,62&lt;/Rate&gt;&lt;Rate curr="CZK" unit="1"&gt;11,02&lt;/Rate&gt;&lt;Rate curr="DKK" unit="1"&gt;40,59&lt;/Rate&gt;&lt;Rate curr="EUR" unit="1"&gt;302,8&lt;/Rate&gt;&lt;Rate curr="GBP" unit="1"&gt;366,05&lt;/Rate&gt;&lt;Rate curr="HKD" unit="1"&gt;28,78&lt;/Rate&gt;&lt;Rate curr="HRK" unit="1"&gt;39,67&lt;/Rate&gt;&lt;Rate curr="IDR" unit="100"&gt;1,88&lt;/Rate&gt;&lt;Rate curr="ILS" unit="1"&gt;63,32&lt;/Rate&gt;&lt;Rate curr="INR" unit="1"&gt;3,58&lt;/Rate&gt;&lt;Rate curr="ISK" unit="1"&gt;1,87&lt;/Rate&gt;&lt;Rate curr="JPY" unit="100"&gt;217,08&lt;/Rate&gt;&lt;Rate curr="KRW" unit="100"&gt;21,04&lt;/Rate&gt;&lt;Rate curr="LTL" unit="1"&gt;87,71&lt;/Rate&gt;&lt;Rate curr="LVL" unit="1"&gt;430,68&lt;/Rate&gt;&lt;Rate curr="MXN" unit="1"&gt;16,89&lt;/Rate&gt;&lt;Rate curr="MYR" unit="1"&gt;69,33&lt;/Rate&gt;&lt;Rate curr="NOK" unit="1"&gt;36,46&lt;/Rate&gt;&lt;Rate curr="NZD" unit="1"&gt;183,65&lt;/Rate&gt;&lt;Rate curr="PHP" unit="1"&gt;5,1&lt;/Rate&gt;&lt;Rate curr="PLN" unit="1"&gt;72,03&lt;/Rate&gt;&lt;Rate curr="RON" unit="1"&gt;67,89&lt;/Rate&gt;&lt;Rate curr="RSD" unit="1"&gt;2,65&lt;/Rate&gt;&lt;Rate curr="RUB" unit="1"&gt;6,71&lt;/Rate&gt;&lt;Rate curr="SEK" unit="1"&gt;34,08&lt;/Rate&gt;&lt;Rate curr="SGD" unit="1"&gt;177,85&lt;/Rate&gt;&lt;Rate curr="THB" unit="1"&gt;6,93&lt;/Rate&gt;&lt;Rate curr="TRY" unit="1"&gt;109,6&lt;/Rate&gt;&lt;Rate curr="UAH" unit="1"&gt;27,14&lt;/Rate&gt;&lt;Rate curr="USD" unit="1"&gt;223,09&lt;/Rate&gt;&lt;Rate curr="ZAR" unit="1"&gt;21,59&lt;/Rate&gt;&lt;/Day&gt;&lt;/MNBCurrentExchangeRates&gt;

I am pasting .NET code to complete the question:

XslCompiledTransform xslt = new XslCompiledTransform();
using (StringWriter writer = new StringWriter())
{
    xslt.Load(xsltPath);
    xslt.Transform(xmlDoc.CreateNavigator(), null, writer);
    string xml = writer.ToString();

    XmlSerializer serializer = new XmlSerializer(typeof(List));
    using (TextReader reader = new StringReader(xml))
    {
        return (List)serializer.Deserialize(reader);
    }
}

Upvotes: 1

Views: 750

Answers (4)

kwitee
kwitee

Reputation: 163

Sorry guys, I misled you. The thing is that the SOAP response is partially escaped:

    <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <GetCurrentExchangeRatesResponse xmlns="http://www.mnb.hu/webservices/">
            <GetCurrentExchangeRatesResult>&lt;MNBCurrentExchangeRates&gt;&lt;Day date="2013-12-04"&gt;&lt;Rate curr="AUD" unit="1"&gt;200,46&lt;/Rate&gt;&lt;Rate curr="BGN" unit="1"&gt;154,44&lt;/Rate&gt;&lt;Rate curr="BRL" unit="1"&gt;93,56&lt;/Rate&gt;&lt;Rate curr="CAD" unit="1"&gt;208,25&lt;/Rate&gt;&lt;Rate curr="CHF" unit="1"&gt;245,79&lt;/Rate&gt;&lt;Rate curr="CNY" unit="1"&gt;36,49&lt;/Rate&gt;&lt;Rate curr="CZK" unit="1"&gt;11,02&lt;/Rate&gt;&lt;Rate curr="DKK" unit="1"&gt;40,49&lt;/Rate&gt;&lt;Rate curr="EUR" unit="1"&gt;302,05&lt;/Rate&gt;&lt;Rate curr="GBP" unit="1"&gt;363,71&lt;/Rate&gt;&lt;Rate curr="HKD" unit="1"&gt;28,67&lt;/Rate&gt;&lt;Rate curr="HRK" unit="1"&gt;39,53&lt;/Rate&gt;&lt;Rate curr="IDR" unit="100"&gt;1,85&lt;/Rate&gt;&lt;Rate curr="ILS" unit="1"&gt;63,13&lt;/Rate&gt;&lt;Rate curr="INR" unit="1"&gt;3,57&lt;/Rate&gt;&lt;Rate curr="ISK" unit="1"&gt;1,86&lt;/Rate&gt;&lt;Rate curr="JPY" unit="100"&gt;216,66&lt;/Rate&gt;&lt;Rate curr="KRW" unit="100"&gt;20,94&lt;/Rate&gt;&lt;Rate curr="LTL" unit="1"&gt;87,5&lt;/Rate&gt;&lt;Rate curr="LVL" unit="1"&gt;429,71&lt;/Rate&gt;&lt;Rate curr="MXN" unit="1"&gt;16,89&lt;/Rate&gt;&lt;Rate curr="MYR" unit="1"&gt;68,9&lt;/Rate&gt;&lt;Rate curr="NOK" unit="1"&gt;36,35&lt;/Rate&gt;&lt;Rate curr="NZD" unit="1"&gt;181,92&lt;/Rate&gt;&lt;Rate curr="PHP" unit="1"&gt;5,07&lt;/Rate&gt;&lt;Rate curr="PLN" unit="1"&gt;71,9&lt;/Rate&gt;&lt;Rate curr="RON" unit="1"&gt;67,62&lt;/Rate&gt;&lt;Rate curr="RSD" unit="1"&gt;2,63&lt;/Rate&gt;&lt;Rate curr="RUB" unit="1"&gt;6,68&lt;/Rate&gt;&lt;Rate curr="SEK" unit="1"&gt;34,08&lt;/Rate&gt;&lt;Rate curr="SGD" unit="1"&gt;177,05&lt;/Rate&gt;&lt;Rate curr="THB" unit="1"&gt;6,89&lt;/Rate&gt;&lt;Rate curr="TRY" unit="1"&gt;108,51&lt;/Rate&gt;&lt;Rate curr="UAH" unit="1"&gt;26,96&lt;/Rate&gt;&lt;Rate curr="USD" unit="1"&gt;222,29&lt;/Rate&gt;&lt;Rate curr="ZAR" unit="1"&gt;21,4&lt;/Rate&gt;&lt;/Day&gt;&lt;/MNBCurrentExchangeRates&gt;</GetCurrentExchangeRatesResult>
        </GetCurrentExchangeRatesResponse>
    </soap:Body>
</soap:Envelope>

I exported the XML from Visual Studio and it automaticaly replaced < and >. But the web service is really treating contents of GetCurrentExchangeRatesResult as string.

I spend almost whole day doing this.

Thanks everyone who helped me solve this problem.

Final XSLT that worked for me - require exsl:node-set function (in case someone would need it):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://www.mnb.hu/webservices/">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="soap:Envelope/soap:Body/ws:GetCurrentExchangeRatesResponse/ws:GetCurrentExchangeRatesResult">
        <xsl:element name="kurzovni_listek">
            <xsl:variable name="details" select="."/>
            <xsl:variable name="parsedXml_">
                <xsl:call-template name="parseXml">
                    <xsl:with-param name="text" select="$details"/>
                </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="parsedXml" select="exsl:node-set($parsedXml_)"/>
            <xsl:attribute name="banka"><xsl:text>MNB</xsl:text></xsl:attribute>
            <xsl:attribute name="datum">
                <xsl:value-of select="$parsedXml/MNBCurrentExchangeRates/Day/@date"/>
            </xsl:attribute>
            <xsl:for-each select="$parsedXml/MNBCurrentExchangeRates/Day/Rate">
                <xsl:element name="kurz">
                    <xsl:attribute name="mena">
                        <xsl:value-of select="@curr"/>
                    </xsl:attribute>
                    <xsl:attribute name="nasobek">
                        <xsl:value-of select="@unit"/>
                    </xsl:attribute>
                    <xsl:attribute name="hodnota">
                        <xsl:value-of select="translate(., ',', '.')"/>
                    </xsl:attribute>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
    <xsl:template name="parseXml">
        <xsl:param name="text"/>
        <xsl:choose>
            <xsl:when test="contains($text, '&gt;')">
                <xsl:variable name="topLevelTag">
                    <xsl:call-template name="getTopLevelTag">
                        <xsl:with-param name="text" select="$text"/>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:variable name="openingTag">
                    <xsl:value-of select="$topLevelTag"/>
                </xsl:variable>
                <xsl:variable name="tagName">
                    <xsl:call-template name="getTopLevelTagName">
                        <xsl:with-param name="text" select="$text"/>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:variable name="closingTag">
                    <xsl:value-of select="concat('&lt;/',$tagName,'&gt;')"/>
                </xsl:variable>
                <xsl:variable name="firstNode">
                    <xsl:if test="not(contains($topLevelTag,'/&gt;'))">
                        <xsl:value-of select="substring-before(substring-after($text,$openingTag),$closingTag)"/>
                    </xsl:if>
                </xsl:variable>
                <xsl:variable name="afterFirstNode">
                    <xsl:choose>
                        <xsl:when test="not(contains($topLevelTag,'/&gt;'))">
                            <xsl:value-of select="substring-after($text,concat($firstNode,$closingTag))"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="substring-after($text,$topLevelTag)"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <xsl:element name="{$tagName}">
                    <xsl:call-template name="createAttributes">
                        <xsl:with-param name="text" select="$topLevelTag"/>
                    </xsl:call-template>
                    <xsl:call-template name="parseXml">
                        <xsl:with-param name="text" select="$firstNode"/>
                    </xsl:call-template>
                </xsl:element>
                <xsl:call-template name="parseXml">
                    <xsl:with-param name="text" select="$afterFirstNode"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$text"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="getTopLevelTagName">
        <xsl:param name="text"/>
        <xsl:choose>
            <xsl:when test="contains($text, '&gt;')">
                <xsl:variable name="tagWithAttributesWithoutEnd">
                    <xsl:value-of select="substring-before($text, '&gt;')"/>
                </xsl:variable>
                <xsl:variable name="tagWithAttributesWithoutBegining">
                    <xsl:value-of select="substring-after($tagWithAttributesWithoutEnd, '&lt;')"/>
                </xsl:variable>
                <xsl:variable name="tagName">
                    <xsl:choose>
                        <xsl:when test="contains($tagWithAttributesWithoutBegining,' ')">
                            <xsl:value-of select="substring-before($tagWithAttributesWithoutBegining, ' ')"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$tagWithAttributesWithoutBegining"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <xsl:value-of select="$tagName"/>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="getTopLevelTag">
        <xsl:param name="text"/>
        <xsl:choose>
            <xsl:when test="contains($text, '&gt;')">
                <xsl:variable name="tagWithAttributesWithoutEnd">
                    <xsl:value-of select="substring-before($text, '&gt;')"/>
                </xsl:variable>
                <xsl:value-of select="concat($tagWithAttributesWithoutEnd,'&gt;')"/>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="createAttributes">
        <xsl:param name="text"/>
        <xsl:choose>
            <xsl:when test="contains($text, '=&quot;')">
                <xsl:variable name="attributeName">
                    <xsl:value-of select="substring-before(substring-after($text,' '),'=&quot;')"/>
                </xsl:variable>
                <xsl:variable name="attributeValue">
                    <xsl:value-of select="substring-before(substring-after($text,concat($attributeName,'=&quot;')),'&quot;')"/>
                </xsl:variable>
                <xsl:attribute name="{$attributeName}"><xsl:value-of select="$attributeValue"/></xsl:attribute>
                <xsl:call-template name="createAttributes">
                    <xsl:with-param name="text" select="substring-after($text,concat($attributeName,'=&quot;',$attributeValue,'&quot;'))"/>
                </xsl:call-template>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

michael.hor257k
michael.hor257k

Reputation: 116958

In response to your new question: both stylesheets work in the same way and produce a result in the form of:

<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:ws="http://www.mnb.hu/webservices/" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">

203,5
154,82
94,69
209,79
...
223,09
21,59

</list>

The only difference between them is the number of blank lines surrounding the values (either one or two). I am not sure how this helps. I am not a .NET programmer, so I am afraid I can't help you there.

Upvotes: 1

michael.hor257k
michael.hor257k

Reputation: 116958

You are missing a for-each statement. Try something like:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:ws="http://www.mnb.hu/webservices/"
exclude-result-prefixes="soap ws">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <list>
        <xsl:for-each select="soap:Envelope/soap:Body/ws:GetCurrentExchangeRatesResponse/ws:GetCurrentExchangeRatesResult/ws:MNBCurrentExchangeRates/ws:Day/ws:Rate">
            <rate>
                <date><xsl:value-of select="../@date"/></date>
                <curr><xsl:value-of select="@curr"/></curr>
                <value><xsl:value-of select="."/></value>
            </rate>
        </xsl:for-each>
    </list>       
</xsl:template>
</xsl:stylesheet>

which will produce a result of:

<?xml version="1.0" encoding="UTF-8"?>
<list>
  <rate>
    <date>2013-12-03</date>
    <curr>AUD</curr>
    <value>203,5</value>
  </rate>
  <rate>
    <date>2013-12-03</date>
    <curr>BGN</curr>
    <value>154,82</value>
  </rate>
  <rate>
    <date>2013-12-03</date>
    <curr>BRL</curr>
    <value>94,69</value>
  </rate>
  ...
  <rate>
    <date>2013-12-03</date>
    <curr>USD</curr>
    <value>223,09</value>
  </rate>
  <rate>
    <date>2013-12-03</date>
    <curr>ZAR</curr>
    <value>21,59</value>
  </rate>
</list>

Upvotes: 1

Mathias M&#252;ller
Mathias M&#252;ller

Reputation: 22617

Here is a way to access the Day and Rate elements. It processes all Day elements in an xsl:for-each expression and matches Rate elements in a separate template.

Also note that this line:

<xsl:template match="//ws:MNBCurrentExchangeRates">

selects MNBCurrentExchangeRates elements no matter where they are in the document. That way, you are spared the exercise of navigating this lengthy tree. (If your goal is indeed to get at the Day and Rate elements).

The stylesheet:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:ws="http://www.mnb.hu/webservices/"
exclude-result-prefixes="ws">

<xsl:output method="xml" indent="yes" version="1.0" encoding="UTF-8" />
<xsl:strip-space elements="*"/>

<xsl:template match="/">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="//ws:MNBCurrentExchangeRates">
  <xsl:element name="list">
     <xsl:for-each select="ws:Day">
        <xsl:copy>
           <xsl:attribute name="date">
              <xsl:value-of select="@date"/>
           </xsl:attribute>
           <xsl:apply-templates/>
        </xsl:copy>
     </xsl:for-each>
  </xsl:element>
</xsl:template>

<xsl:template match="ws:Rate">
  <xsl:copy>
     <xsl:copy-of select="@*|text()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

This yields the following output:

<?xml version="1.0" encoding="UTF-8"?>
<list>
 <Day xmlns="http://www.mnb.hu/webservices/"
    xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    date="2013-12-03">
  <Rate curr="AUD" unit="1">203,5</Rate>
  <Rate curr="BGN" unit="1">154,82</Rate>
  <Rate curr="BRL" unit="1">94,69</Rate>
  <Rate curr="CAD" unit="1">209,79</Rate>
  <Rate curr="CHF" unit="1">246,21</Rate>
  <Rate curr="CNY" unit="1">36,62</Rate>
  <Rate curr="CZK" unit="1">11,02</Rate>
  <Rate curr="DKK" unit="1">40,59</Rate>
  <Rate curr="EUR" unit="1">302,8</Rate>
  <Rate curr="GBP" unit="1">366,05</Rate>
  <Rate curr="HKD" unit="1">28,78</Rate>
  <Rate curr="HRK" unit="1">39,67</Rate>
  <Rate curr="IDR" unit="100">1,88</Rate> 
  <!--And so on...-->   
 </Day>
</list>

Upvotes: 1

Related Questions