ASP.NET: Let's Jazz Up the Xml Control

by Peter A. Bromberg, Ph.D.

Peter Bromberg
An appeaser is one who feeds a crocodile - hoping it will eat him last. -- Sir Winston Churchill

Recently I read on the MS ASP.NET newsgroup where somebody was complaining that the Xml Control would not load his documents from a url ("http:/..."). It only accepts a virtual path (a valid path to a file-based resource in the ASP.NET web application). He thought there was something wrong with his code. This is very common among developers - we try to do something, then get an exception message that is about as plain as day, and yet we fail to understand it. Most of the time if you will just SLOW DOWN AND READ -- the meaning will come through loud and clear, and you can save yourself some time!



The compiler and Runtime exception messages are generally very clearly written; it's we as developers who need to get our heads screwed on right and get away from this "Its a BUG" mentality.

At any rate, Peter Kellner, whose work I particularly like, chimed in and showed how this individual could use HttpWebRequest to get the document, and then assign it to the control's Document property. However, that made me think a bit. Why doesn't the Xml Control allow you to load its required XmlDocument and Xsl Stylesheet documents remotely? You'd think it should, right?

So, silly me, I went and created a new CustomXml Control derived from the base control, and Voilà! we have a control with two new properties, DocumentUrl and XslUrl! Fill them in and you are good to go! (By the way, that's a French word. It's not "Viola", or "Walla" it's Voilà with an accent grave over the "a". It means literally, "See there!" e.g., "there you are!"[Il est dommage que les Américains pensent que la seule langue dans le monde est l'anglais.])

The whole project took about 15 minutes, and a good part of that was messing around with XPathNavigator since the original properties are deprecated in ASP.NET 2.0, and I figured if I was going to use it for a while, I'd better go ahead and take care of those niceties now, rather than waiting for them to be gone in a future version.

Now that our short lesson in usage of foreign terms of speech is over, let's get to how to do this in code:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Text;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Net;

using System.Xml;

using System.Xml.Xsl;

 

namespace PAB.WebControls

{

    [DefaultProperty("DocumentUrl")]

    [ToolboxData("<{0}:CustomXml1 runat=server></{0}:CustomXml1>")]

    public class CustomXml : System.Web.UI.WebControls.Xml

    {

        [Bindable(true)]

        [Category("Appearance")]

        [DefaultValue("")]

        [Localizable(true)]      

        private string _documentUrl;

        public string DocumentUrl

        {

            get

            {

                return _documentUrl;

            }

 

            set

            {

                _documentUrl = value

                System.Xml.XPath.XPathDocument xDoc = new System.Xml.XPath.XPathDocument(_documentUrl);

                this.XPathNavigator = xDoc.CreateNavigator();

            }

        }

 

        private string _xslUrl;

        [Bindable(true)]

        [Category("Appearance")]

        [DefaultValue("")]

        [Localizable(true)]  

        public string XslUrl

        {

            get

            {

                return _xslUrl;

            }

 

            set

            {

                _xslUrl = value;

                System.Xml.XPath.XPathDocument xslDoc = new System.Xml.XPath.XPathDocument(_xslUrl);

                System.Xml.XPath.XPathNavigator xslNav = xslDoc.CreateNavigator();              

                XslTransform xsltran = new XslTransform();

                xsltran.Load(xslNav);

                this.Transform = xsltran;             

            }

        }

    }

}

That's all you need to do, the base control works the same way, so you don't need to write any more code than what is shown above; the inherited functionality "comes along for the ride" - part of the beauty and elegance of .NET.

To use this, just stick the class into the APP_CODE folder, or the compiled assembly into the /bin folder. You can right-click on the toolbox and add it, and then drag it onto the design surface of a page and set the new properties.

This is not a trivial exercise; I've seen entire web sites developed around this control -- where the content is all Xml and it gets styled to present the actual page that you see. If you ever expect to be able to display RSS feed or Search results (RSS format) content from remote URLs, you will definitely need this enhanced, "ShouldaBeenThereInTheFirstPlace" technology.

The solution I've included below will remotely load the Eggheadcafe.com main rss feed xml document along with the famous "rsspretty.xsl" stylesheet, apply the transform, and the page will look a lot like the display from the IE 7 RSS feed page displays. Enjoy.

Download the Visual Studio 2005 Solution accompanying this article


Peter Bromberg is a C# MVP, MCP, and .NET consultant who has worked in the banking and financial industry for 20 years. He has architected and developed web - based corporate distributed application solutions since 1995, and focuses exclusively on the .NET Platform.
Article Discussion: