Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XSLT Webservice... 1

Status
Not open for further replies.

modinrico

Programmer
Apr 30, 2008
8
US
OK New Question...
Just when i think I can say Vioala!!! i got it friggin the bird poops on my head ;)

I am trying to load my Second XML page from a web service. Cool right? Should be simple. Set upt he webservice for http:Get and cool im getting xml back yay. But its incorrect becaues for somereason the output of The Webservice has all of the <> converted to &gt;&lt; what do i do to solve this problem...


<xsl:variable name="ws" select="'<xsl:variable name="url" select="'demo'"/>
<xsl:variable name="ssnetData" select="document(concat($ws, $url))"/>

Your help is appreciated
 
Where are you seeing the &gt; and &lt;?

It is most likely due to how you are using "ssnetData".

Are you using xsl:value-of or xsl:copy-of?
 
Hey if you can help me figure this out that would be great I am using <xsl:value-of

here is a good chunk of the XSL

<xsl:variable name="ws" select="' <xsl:variable name="url" select="'demo'"/>
<xsl:variable name="ssnetData" select="document(concat($ws, $url))"/>


<salescenterimport>
<xsl:value-of select="$ssnetData"/>

<builder action="update" >
<xsl:attribute name="code">
<xsl:value-of select="$ssnetData/builder/@code" />
</xsl:attribute>
<name>
<xsl:value-of select="$ssnetData/builder/@name" />
</name>
<county>
<xsl:value-of select="$ssnetData/builder/@country" />
</county>
</builder>

<xsl:for-each select="$ssnetData/builder/division">
<division action="update">
<code>
<xsl:value-of select="@code" />
</code>
<name>
<xsl:value-of select="@name" />
</name>


<xsl:for-each select="$CDCI/ToSales/Customer/Model/Standard/Elevation">
<option action="update">
<code>
<xsl:value-of select="@ID" />
</code>
<description>
<xsl:value-of select="@Description" />
</description>
<longdescription>
<xsl:value-of select="@BaseComment" />
</longdescription>
<price>
<xsl:value-of select="@PkgAmount" />
</price>
</option>
</xsl:for-each>
 
[0] Just to make sure I understand or you understand, the line like this:
><xsl:value-of select="$ssnetData"/>
results somthing like concatinating all the text nodes... So I suppose what you see &lt; &gt; etc come from those text nodes, not from the element node construction of a normal xml document.

[1] In that case, you can do this for xslt 1.0 everywhere where you query and select the text.
[tt]<xsl:value-of select="$ssnetData" [blue]disable-output-escaping="yes"[/blue] />[/tt]

[2] In xslt 2.0, you have another option to use xsl:character-map to specify the replacement of &lt; and &gt;, and add an attribute of use-character-maps, pointing to the xsl:character-map element's name attribute, to the xsl:eek:utput element.
 
The problem is that i am trying to get it usable. If I select all of it then the data comes escaped. And if I select a <xsl:value-of select="$ssnetData/builder/@code" />

it doesn't work. How do i get the data down from the webservice in a usable state?
 
Since you are just interested in monologue, I cannot help. I don't understand a bit what you mean, usable, escaped, doesn't work...
 
Ok i put the web service out there for you to test this with..

Here is my XSL
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl=" version="1.0">
<xsl:eek:utput method="xml" indent="yes"/>

<!-- load the merge file -->


<xsl:template match="/">
<xsl:variable name="CDCI" select="document(/)"/>


<xsl:variable name="ws"

select="' <xsl:variable name="url" select="'''Sales%20Simplicity%20Software'''"/>


<xsl:variable name="ssnetData2" select="document(concat($ws, $url))" />

<xsl:variable name="ssnetData" >
<xsl:copy-of select="$ssnetData2" />
</xsl:variable>




<salescenterimport>
<builder action="update" >
<xsl:attribute name="code">
<xsl:copy-of select="$ssnetData/builder/@code" />
</xsl:attribute>
<name>
<xsl:value-of select="$ssnetData/builder/@name" />
</name>
<county>
<xsl:value-of select="$ssnetData/builder/@country" />
</county>
</builder>



</salescenterimport>
</xsl:template>
</xsl:stylesheet>

Basically if you run this xsl you will recieve XML back but nothing is filled out Code, Country, Name should all be filled in the data is there. But it doesn't happen..

what am i doing wrong?
 
[3]
><xsl:variable name="CDCI" select="document(/)"/>
What is document(/)? It can't be correct!
><xsl:variable name="url" select="'''Sales%20Simplicity%20Software'''"/>
What are all those multiple single-quotes?

[4] Why copy-of? What is the point of deep copy of an attribute which is leaf?
><xsl:copy-of select="$ssnetData/builder/@code" />

[5] Now, return to my original reponse: you never seem to try or understand. Apply the attribute setting disable-output-escaping according to need.
[5.1]
><xsl:value-of select="$ssnetData/builder/@name" />
[tt]<xsl:value-of select="$ssnetData/builder/@name" [blue]disable-output-escaping="yes"[/blue] />[/tt]
[5.2]
><xsl:value-of select="$ssnetData/builder/@country" />
[tt]<xsl:value-of select="$ssnetData/builder/@country" [blue]disable-output-escaping="yes"[/blue] />[/tt]
 
3) That is another document i am bringing in locally not from webservice... We can ignore that for now. THose aren't multiple single quotes it is 2 single quotes (to escape it) and one double quote. It serves its purpose. Did you run the XSLT it works it pulls the data from the webservice ill explain the issue

4) I am just trying everything. Neither Value of or copy of work...

5) I did try disable-output-escaping the issue is that it doesn't work for my scenario.
When i load <xsl:variable name="ssnetData2" select="document(concat($ws, $url))" /> the value in ssnetData2 has the Escaped Values with the "&LT;" and "&GT;" therefore not making it USEFUL to me. it doesn't load it as parsed XML but more as a string. and I can't put the disable-output-escaping in that line. Hence why below it I was trying to use
the Disable-output-escaping on this line
<xsl:variable name="ssnetData" >
<xsl:copy-of select="$ssnetData2" /> <-- I was trying to use the disable output escaping here but it didn't work...
</xsl:variable>


So when i do this: <xsl:value-of select="$ssnetData/builder/@name" /> it doesn't get a value no matter what i do. I am lost as to what i am doing wrong. The Webservice is posted if you wanna try and run the XSLT maybe you will understand a little better..

I don't know how to explain it differently. I think you will know the answer when you try it out once or twice you will encounter my error and it will make sense. maybe..




 
Further notes

[6] What for?
><xsl:variable name="ssnetData" >
> <xsl:copy-of select="$ssnetData2" />
> </xsl:variable>

[6.1] Just take them all out, and define the ssnetData directly and replacing ssnetData2,
[tt]<xsl:variable name="[red]ssnetData[/red]" select="document(concat($ws, $url))" />[/tt]
under the condition that your $ws and $url are error-free. Note that the root element of the ssnetData2 would be "builder". Make sure it is what it should be.
 
I posted the above missing the reply.

My impression of browsing your response is you are trying trying trying without a base. Is computing an experimental science?

Make sure your ssnetData so defined according to my [6] be done correctly. If it is not correct, nothing would work.

What have you put up as ws? I haven't tried it. Do I need to try it to know? if your xslt document is incorrect.
 
Tsuji,
You speak as if you are better than me or something. But yet you can't seem to understand my questions. Computing is not an experimental science but when I can't find a sollution I create several test scenarios with my problem in them so that I can understand my problem better. If you have an answer you have an answer but if you don't there is no need to try to demean me. Unless it makes you feel better then feel free do say act how you want. I am simply trying to find an answer to a question. you offered an idea I looked up the idea it does as advertised but it can not be used when defining a variable. My example was simply to show you the problem and the things that are going that cause the problem. And maybe you being as intelligent as you are can simply say hey make these changes and it will all work but you havn't shown your God like Feature that you think you have.

If you take out the idea that it is connecting to a web service and load ssnetData as a Local XML file the whole XSLT works exactly as I need designed it to. But when I connect it to a web service it no longer works.

The reason it no longer works is because when it is calling the webservice the webservice automatically URL Encodes the String coming from the web service since it is an HTTP GET call to the Web Service.

Since everything is URL Encoded the Variable isn't seen as a XML document but a String So it can not be accessed using <xsl:value-of select="$ssnetData/builder/@name" />






 
Okay, with the time to calm yourself, I am planning to give you a long response to resolve the problem and show you different facets of it. As I write in real-time, I would foresee I would need at least two posts to complete my opinions (not advice, so that I don't appear "I am better or something").

[99] First thing first. Don't take it too heavy.
>You speak as if you are better than me or something. But yet you can't seem to understand my questions.
Okay, you win, you are better. Are you happy? But I normally do not take this kind of thing declarative. People say I did this, I did that, so big the project, so big the achievement. Me, I don't take it. If they are better, demonstrate it in answering/helping people's questions. Make this forum performing and well-regarded. Not just empty statement, bavardage. Nothing personal toward you, I even think you're okay because at least you care the problem, not like manay others. I think I can leave the subject for good with you.

Now back to business.

[3.1]
><xsl:variable name="url" select="'''Sales%20Simplicity%20Software'''"/>
You care to give explanation of it. I think I know good enough of HTTP Get. I am not very much like the quoting the querystring. There is no need at all. But if your serve-side program coded the additional quotes, then, you do have to stick to it. (I think you can modify that part as it is really not very good and pose very annoying problem on consumming the service, see below.)

[3.1.1] Now, the xslt document appeals to version 1.0 recommendation. In that case, doubling up apostrophe to escaping it is _[red]not[/red]_ in the spec. It is xslt 2.0.

[3.1.2] But, and there is a big but, if you use specifically some special implementation, it can in fact accept xslt 2.0 escaping scheme in xslt 1.0 fall-back. This is the case for instance Saxon. The rest, I have no specifically testing out. Msxml2 will reject it, breaking all the rest of the script. Hence, your script has zero chance to work on ie.

[3.1.3] The xslt 1.0 realization of the line is tricky. It is this.
[tt]<xsl:variable name="url" select="concat(&quot;'&quot;, 'Sales%20Simplicity%20Software', &quot;'&quot;)"/>[/tt]
It doesn't look great.

[3.1.4] The opinion still is that there is no need to quote the querystring in Get if the server-side code is altered without sacrifice none. It is up to you.

[3.2]
><xsl:variable name="CDCI" select="document(/)"/>
It is a really questionable line. But you said no need to worry about it and you do not show the part using CDCI, I leave it as such.

[7] Cascaded xslt transformation

[7.1] I can now show you how to obtain an output xml document using the setting I'd mentioned. If you persist the output document (by saving a hard copy of the output xml document, you will see it is the good ussal xml document of its own ready for processing in cascade.)
[tt]
<?xml version="1.0"?>

<!-- gt:note test also version 2. It is important for '' type of escape
<xsl:stylesheet xmlns:xsl=" version="2.0">
-->

<xsl:stylesheet xmlns:xsl="[ignore][/ignore]" version="1.0">
<xsl:eek:utput method="xml" indent="yes" [red]omit-xml-declaration="yes"[/red] />

<xsl:template match="/">
<xsl:variable name="ws" select="' [blue]<xsl:variable name="url" select="concat(&quot;'&quot;, 'Sales%20Simplicity%20Software', &quot;'&quot;)"/>[/blue]
<xsl:variable name="[red]ssnetData[/red]">
<xsl:value-of select="document(concat($ws, $url))" />
</xsl:variable>
<xsl:value-of select="$ssnetData" disable-output-escaping="yes" />
</xsl:template>
</xsl:stylesheet>
[/tt]
[7.2] The output stream is to feed to an 2nd stage xslt document to further transform it into
[tt]<salecenterimport>
<!-- ... etc --->
</salecenterimport>[/tt]

[7.3] That is not by itself a shortcoming. It is the normal course of business of xslt. In an application consumming the ws, it does not pose special difficult. If you persist a hard copy of the output, you will see it is the correct xml document.

[7.3.1] In the course of the transformation, you have to put
[tt]omit-xml-declaration="yes"[/tt]
highlighted above. It is important, otherwise, the feed to the tandum transformation will be erroneous. Other details I won't further highlight them, they appeared one way or another in my preceding posts.

[8] Processing in single xslt. I will post the method in the following post, as I feel already tiring and need a break of couple of minutes and also let you digest the above.
 
[8] Processing in single xslt

[8.1] It can only be done with extension function in xslt 1.0. It needs to parse the string into xml document. That part is outside of the scope of xslt.

[8.2] I can show how to get it done with msxml2 extension. This is one way of doing.
[tt]
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="[ignore][/ignore]" version="1.0"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:tsuji-tt1470379:test"
exclude-result-prefixes="msxsl user">

<msxsl:script language="vbscript" implements-prefix="user">
<![CDATA[
dim xmldoc
function go_parse(onl)
dim s
s=onl.item(0).text

dim oparser
set oparser=createobject("msxml2.domdocument")
with oparser
.async=false
.resolveexternals=true
.validateonparse=false
end with

s=replace(s,"&lt;","<")
s=replace(s,"&gt;",">")

iret=oparser.loadxml(s)
set xmldoc=oparser 'setup global xmldoc
if iret then
go_parse="done"
else
go_parse="failed"
end if
set oparser=nothing
end function

function get_attr(attr)
dim svalue
if not (xmldoc is nothing) then
svalue=xmldoc.selectsinglenode("/builder/@" & attr).nodevalue
else
svalue=""
end if
get_attr=svalue
end function
]]>
</msxsl:script>

<xsl:eek:utput method="xml" indent="yes" />

<!-- load the merge file -->

<xsl:template match="/">
<xsl:variable name="ws" select="'[ignore][/ignore]'"/>
<xsl:variable name="url" select="concat(&quot;'&quot;, 'Sales%20Simplicity%20Software', &quot;'&quot;)"/>
<xsl:variable name="ssnetData">
<xsl:value-of select="document(concat($ws, $url))" />
</xsl:variable>
<xsl:variable name="xmldoc_ssnetData">
<xsl:value-of select="user:go_parse($ssnetData)" />
</xsl:variable>

<salescenterimport>
<xsl:if test="$xmldoc_ssnetData = 'done'">
<builder action="update">
<xsl:attribute name="code">
<xsl:value-of select="user:get_attr('code')" />
</xsl:attribute>
<name>
<xsl:value-of select="user:get_attr('name')" />
</name>
<county>
<xsl:value-of select="user:get_attr('country')" />
</county>
</builder>
</xsl:if>
<xsl:if test="$xmldoc_ssnetData = 'failed'">
<!-- put error message -->
</xsl:if>
</salescenterimport>
</xsl:template>
</xsl:stylesheet>
[/tt]
[8.3] Extension entails platform dependent. In other platform, the leading idea is still the same, one has just to implement it with some work.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top