Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Thursday, January 10, 2008

Vista Sidebar Gadgets, Silverlight and JSON

ok, so I've posted about JSON in sidebar gadgets before and using Silverlight... when it comes to JSON (in vista side bar gadgets) just say no. at least directly, there are soooo many issues with this that it is unbelievable not to mention I'm running on a 64bit box that shouldn't even run silverlight to begin with the issues are not even consistent across different variations of vista and silverlight... really this is killing me. I found that it is eaiser to just make xml calls which is what I normalled used todo before some one came up with this brillant JSON thing... not that it is a real protocol and all but it is slick, anyway don't use JSON directly in a side bar gadget especially with Silverlight.

That being said, there are a number of ways doing old fashioned xml posting to get what you need and you can just parse and do the old fashioned xml thing and if your extra Industrious or need to write out something and the JSON eval thing solves some problems for you (namely less work) then add some begin and end tags and a nice CDATA section and your good...

But if you find a pratical way todo this let me know (JSON, sidebar gadget, vista, silverlight...), I'd love to see a code sample.

Tuesday, November 27, 2007

Silverlight Preloader animation is the answer

I got this email today:

Hi!
In our project we call a function which retrieves a data from a webservice.
This function takes some time 1-3 seconds.
This we do in the end of the OnLoad event.
This causes the application not to appear immediately and is not drawn until the retrieve function is finished.
How can we let the application finish rendering and then invoke the retrieve function?
Then we could put up a message to ask the user to wait while loading.
Is there any onRendered event in Silverlight?
Or could be put a custom event back to the event queue some how, then we could emit an event which calls the retrieve function after the rendering is finished?
Best regards,
Haraldur


In most complicated Silverlight applications I generally have a preloader animation. So when the silverlight application first loads it shows some little animation that runs on the canvas loaded event until some other method is called that stops the animation and fades in the UI etc.

Using the downloader object this is pretty straight forward as you can add a delegate to the downloader object and then the delegate gets called when the download is complete and it can do something to get the application running. a simple example is:

var downloader = this.control.createObject("downloader");
downloader.addEventListener("completed", Silverlight.createDelegate(this, this.MediaClipDownloadCompleted));
downloader.open("GET", "control/MediaClip.xaml");
downloader.send();

in this case the downloader is pulling some xaml but really it could be anything. when complete the method 'MediaClipDownloadCompleted that in this case looks like this:

MediaClipDownloadCompleted: function(sender, eventArgs)

{

var xamlItem = sender.getResponseText("");

MediaClipClass = new MediaClipBaseClass( xamlItem );

MediaClipClass.LoadTarget( this.control.content, this.root.findName("MediaTarget"), 50, 100, "test/sample.wmv", "test/thumb.png" );

}

anyway working with the HTTPRequestObject is similar. take this code for example:

this.HTTPRequestObject.open("GET", this.url, true); this.HTTPRequestObject.onreadystatechange = this.XMLObjCallback; this.HTTPRequestObject.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); this.HTTPRequestObject.send(null);

basically we set the 'onreadystatechange' to our delegate that deals with things when the request is returned. In this case the method looks like this:

XMLObjCallback: function( )
{ // Check for the completed status
if (_XMLRef.HTTPRequestObject.readyState == 4)
{ // Check for successful server response
if (_XMLRef.HTTPRequestObject.status == 200)
{
if( _XMLRef.XML == "" )
{
_XMLRef.XML = _XMLRef.HTTPRequestObject.responseText;
}
if (!window.ActiveXObject)
{
var parser = new DOMParser();
_XMLRef.XmlDocument = parser.parseFromString(_XMLRef.XML,"text/xml");
}
else //is i.e
{
_XMLRef.XmlDocument = new ActiveXObject("Microsoft.XMLDOM");
_XMLRef.XmlDocument.async = "false";
_XMLRef.XmlDocument.loadXML(_XMLRef.XML);
}
}
else
{ // HTTP error
alert('Error: ' + _XMLRef.HTTPRequestObject.status);
}
}
},

its a bit complicated but basically when the code returns it does its thing. For more information on XML see these previous posts:

http://hackingsilverlight.blogspot.com/2007/10/parsing-xml-in-silverlight-10-cross.html

and this code sample

http://www.HackingSilverlight.net/samples/XMLParser.zip

also look at some of the bits in 1.1 and hopefully the new 1.1 drop that comes soon will have some more goodness for us.

Friday, October 26, 2007

Parsing XML in Silverlight 1.0 - Cross Browser

One problem we have seen and dealt with allot lately is parsing XML client side. My favorite solution I must admit is to just toss out XML and use JSON as it is so much more elegant. In the case of the ET Minisite we did as of late this turned out to solve a lot of our problems. But still what if I can't do JSON for whatever reason? if you only care about IE or even firefox that seems to be much less of a problem. But for a really cross browser experience I my solution is the XML document mini me. Granted this is a bit of hack (like much of JavaScript and Silverlight)... :) but it works well... IF your XML is pretty stable and IF there isn't to much XML weirdness like multipul nested levels and such but it works.

So the XML Mini me is a simple XML parseing engine written in Javascript. It only supports a limited subset of something like the real xml parser in .NET like XMLReader or even XMLDocument but it does so a few simple things including some simple xPath like behavior. I hestiate to say a subset of xpath as the mini me is so extremely limited. I also suspect that the silverlight team at some point will have a good XML parser built in to silverlight at some point but we will see. there is of course Silverlight 1.1 but if you can't do the .NET part it doesn't do much goo.

In Silverlight, you have the downloader object so its really reasonable get XML easily no matter what. So then using the XML mini me looks something like this:

var MyDom = new XMLDocument();
MyDom.LoadXML( SomeXML);

I tried to keep the syntax as famliar as possible. So now we have our XMLDOM called 'MyDom' and then to get data out we can do this:

var ArrayOfVAlues = MyDom.SelectNodes("//items");

In this case the mini me will return all the text values of all the items nodes in the dom in the form of an array. Underneath the covers the parser is just doing some 'string' manipulation but for small groups or data or simple RSS feeds or config files it seems to work well. large XML parseing would scary me preformance wise as would writing a more full featured parser that is entirely written in JavaScript.

Some things to note on the class is that it has an XML property like the XML parser we used to use in classic ASP but otherwise it only has two methods currently as those are the ones I need to get it working for my particular project. lets look at the XML it can deal with for starters, here is a sample:




http://www.hackingsilverlight.com


http://www.hackingsilverlight.com


http://www.hackingsilverlight.com


http://www.hackingsilverlight.com


http://www.hackingsilverlight.com




So in this sample using some simple xml our parse deals with it easily. In this case when we make a call to SelectNodes("//url") we will get an array of all the urls values with all the < ! [ CDATA stuff stripped off into an array. simple, easy and fast but easly breakable if you muck up the xml to much. So for the time being its a great stop gap and if JavaScript works then this works at it uses only intrinsic language features.

So the little XML mini me is great for simple stuff but when you really need to do real work with XML you really need a more robust solution that includes a real XML parser. Now that can prove problematic especially when it has to work in lots of browsers. To address this problem with my own work I wrote another class that wraps the cross browser functionality and wraps some key elements that I use. Typically I need things like all of properties of a given node in a list in the form of an array. Plus things like xPath and the like for Silverlight.

So the attached javascript class wraps the core functionality. It includes the HTTP request functionality and XML parsing with the other bits I 'might' need. Basically the class works like this:

var NewDOM = new XML();
NewDOM.Load("Sample.xml");

This code fires when the html page script code behind fires. When you call 'Load' and pass a url to an xml file it then depending on the browser it uses the appropriate HTTP request object to load the file and assign the onload event. On the XML files load the call back is called and the object does the appropriate processing. Once this does its thing we now can use it to parse our XML.

On the onload event for the page in my little test I make two calls to different methods. The same methods are supported on this class as the XML mini me but additional ones are included like 'SelectNodesAttributes'. Also I noticed in firefox by 'onload event gets called twice so I put a flag on it so it only fires once. So in this sample I call the two methods that return arrays but you can have direct access to the DOM and use xPath etc using NewDOM.XmlDocument.