[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Xml file in an Xml file


Subject: Re: [xsl] Xml file in an Xml file
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Wed, 04 Apr 2007 18:17:31 +0200

Danny Leblanc wrote:
Hello everyone.

Using web services I am getting the following XML file returned to me.

<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:XS="http://www.w3.org/2001/XMLSchema"
xmlns:XI="http://www.w3.org/2001/XMLSchema-instance"
xmlns:a="http://www.webserviceX.NET"><S:Body><a:GetWeatherResponse><a:GetWeatherResult XI:type="XS:string">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;CurrentWeather&gt;
&lt;Location&gt;Montreal / Pierre Elliot Trudeau International Airport, Que, Canada (CYUL) 45-28N 073-45W 36M&lt;/Location&gt;
&lt;Time&gt;Apr 04, 2007 - 11:00 AM EDT / 2007.04.04 1500 UTC&lt;/Time&gt;
&lt;Wind&gt; from the ESE (120 degrees) at 15 MPH (13 KT) gusting to 28 MPH (24 KT):0&lt;/Wind&gt;
&lt;Visibility&gt; 6 mile(s):0&lt;/Visibility&gt;
&lt;SkyConditions&gt; overcast&lt;/SkyConditions&gt;
&lt;Temperature&gt; 37 F (3 C)&lt;/Temperature&gt;
&lt;DewPoint&gt; 33 F (1 C)&lt;/DewPoint&gt;
&lt;RelativeHumidity&gt; 86%&lt;/RelativeHumidity&gt;
&lt;Pressure&gt; 29.79 in. Hg (1008 hPa)&lt;/Pressure&gt;
&lt;Status&gt;Success&lt;/Status&gt;
&lt;/CurrentWeather&gt;</a:GetWeatherResult></a:GetWeatherResponse></S:Body></S:Envelope>



What I would like to do is "yank out" the second Xml file that is contained at S:Envelope/S:body/a:GetWeatherResponse/a:GetWeatherResult.

Your web service is getting things wrong. You are not given an XML node here, but a string that resembles an XML snippet. It would be much better to user Web Services for what they are intended for: sending around XML envelopes (instead of escaped XML data as strings).


I tried the following Xslt code using the latest Altova engine

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:XS="http://www.w3.org/2001/XMLSchema" xmlns:XI="http://www.w3.org/2001/XMLSchema-instance" xmlns:a="http://www.webserviceX.NET">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<NewRoot>
<xsl:value-of select="/S:Envelope/S:Body/a:GetWeatherResponse/a:GetWeatherResult"/>
</NewRoot>
</xsl:template>

The value-of gives you the "value of", that is the _string_ value of the data you point to.


<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

This (above) part is never reached because of your match="/" and the absence of apply-templates.


</xsl:stylesheet>

What I get back is <snip />

You get back the string value. You seem to want to take this string value and interpret is as XML and re-apply templates to it. This is not possible easily, unless you can use extension functions like saxon:parse (but then you have to switch to Saxon instead of Altova XSLT parser, which is a good switch towards better standards support and compliance). That said, it is better to cure the problem at the root: the envelope is filled wrongly.




What I would actually like to be returned is a true XML file where I could access all the nodes using Xpath, not a "parsed out" version of the file.

It is not "parsed out", it is precisely what is in that node.


For example

<?xml version="1.0" encoding="utf-8" ?> <NewRoot>
<CurrentWeather>
<Location>Montreal / Pierre Elliot Trudeau International Airport, Que, Canada (CYUL) 45-28N 073-45W 36M</Location> <Time>Apr 04, 2007 - 11:00 AM EDT / 2007.04.04 1500 UTC</Time> <Wind>from the ESE (120 degrees) at 15 MPH (13 KT) gusting to 28 MPH (24 KT):0</Wind> <Visibility>6 mile(s):0</Visibility> <SkyConditions>overcast</SkyConditions> <Temperature>37 F (3 C)</Temperature> <DewPoint>33 F (1 C)</DewPoint> <RelativeHumidity>86%</RelativeHumidity> <Pressure>29.79 in. Hg (1008 hPa)</Pressure> <Status>Success</Status> </CurrentWeather>
</NewRoot>

Which is what I would call a "parsed out" version of your string. See my comments above.


There are a few differences that I would also like, I don't need the namespace declarations. Is there anyway to do this using xslt or am I dreaming?

Getting rid of unused namespaces is easy: use exclude-result-prefixes on the xsl:stylesheet element.


No, you are not dreaming. But what you are asking is something not provided by the XSLT standard: take a string, interpret its contests as if it were XML and re-apply it. But like I said, there are extension functions (you could also write your own, but not sure Altova lets you do that, though it should, actually) that do this for you. But you loose any control on the content really being XML, a typo will likely crash or otherwise mess up your result. So, fixing it at the root and let the SOAP envelope contain what it should contain really is the much easier way to go.

Cheers,
-- Abel Braaksma


Current Thread
Keywords