Tutorials Forums
     Tutorials Videos
        Sign Up Now For FREE
Welcome, Guest
Username Password: Remember me

Enhancing The Web Browser Control For XML
(1 viewing) (1) Guest
A programming language that evolved in part from Microsoft C++, C# was designed for building enterprise-level applications that run on the .NET Framework. C# is simple, modern, type safe, and object oriented. Whether you’re new to the language or an old pro, you’ll find articles in this section that will help you get your projects done.
  • Page:
  • 1

TOPIC: Enhancing The Web Browser Control For XML

Enhancing The Web Browser Control For XML 10 Apr 2010 01:36 #336

Introduction
I've read and heard comments lamenting the fact that the MS .net Web Browser control (System.Windows.Forms.WebBrowser) doesn't behave like Internet Explorer, or lacks some of the feature support that IE has. Chief among these complaints is the one that it doesn't support the displaying of XML the way IE does, all pretty and ready for printing. You could take the view, as do I, that this is the way it should be. The Web Browser control is a basic (although powerful) managed wrapper for the Web Browser ActiveX control (in Shdocvw.dll). IE uses Shdocvw.dll too, but when you use a .net Web Browser control in your application, you're not using a component of IE, you're using a component that IE uses. IE extends it's functionality, and if the need arises... so must you.

So Very Useful
Since the basic WB control can be so useful in many different applications that you develop, I recommend you consider creating a wrapper of your own which you reuse in each project where you need a WB control. As you progress from project to project, you'll add more features as needed by each project. Each time you do this, you potentially save yourself a lot of time with each new project you use it in. You can either put it into its own class library project, as I have in this article. Alternatively you could maintain one code file which you keep importing into other projects. The latter approach requires you to be using a version control or file repository system (such as SourceSafe) so that you can have the same physical file in many projects. Besides that, you may have other class files that you want to add later. So I would suggest building your own library to contain it.
No Need - There's One Right Here
So that's the approach I've taken with the project files associated with this article. I've created a Class Library that contains one class which, using my extensive imagination and creative flare I have named... 'WebBrowser'. This is of course a wrapper for... you guessed... the WebBrowser. For those new to the subject of inheritance, the distinction between the two rests in the fact that EnhancedControls.WebBrowser (my namespace) inherits from, and extends System.Windows.Forms.WebBrowser (an MS namespace). So the issue my WB control will tackle is the one I mentioned at the start - support for displaying XML. But you can add other features to it that are appropriate for your needs too.
Transforming XML
Some people are prone to turning this subject into rocket science. My view is that if a transformation works with the XML files you're working with... it works. Compile the code, make the coffee, and move on. You can always add support for other transformations later on when you encounter some XML with which it doesn't work, if that ever happens. So when I went out looking for a good transformation I found one provided by Steve Muench. I embedded that xslt file into the resources of my library project because I don't want my library to have any dependencies on files external to itself.

Once you have an appropriate transformation at hand, actually making the transform happen is very easy. Here is the code for that:
        /// <summary>
/// Displays XML contained in an XmlReader object using a basic transform.
/// </summary>
/// <param name="oReader">An instance of an XMLReader object</param>
/// <remarks></remarks>
public void DisplayPrettyXML(XmlReader oReader)
{
try //to display the XML contained in the Reader
{
//If I don't currently have a Transformation object then...
if (moXsltTransformation == null)
{
//Create one. This object will be reused on each call to any
//of the DisplayPrettyXML overloads.
moXsltTransformation = new XslCompiledTransform(false);
//Create a TextReader and load it with the xslt file from my resources
using (TextReader oTextReader = new StringReader(Properties.Resources.PrettyPrint))
{
//Create an XmlReader from the TextReader
using (XmlReader oXsltReader = XmlReader.Create(oTextReader))
{
//Load the style sheet into the Transformation object
moXsltTransformation.Load(oXsltReader);
}
 
}
 
}
//If I don't currently have a stringbuilder object then...
if (moStringBuilder == null)
{
//Make one. This object will be reused on each call to any
//of the DisplayPrettyXML overloads.
moStringBuilder = new StringBuilder();
}
else //Otherwise, reuse the one I have. Empty it.
{
moStringBuilder.Remove(0, moStringBuilder.Length);
}
//Create an XmlWriter that will fill the stringbuilder with xml
using (XmlWriter oXmlWriter = XmlWriter.Create(moStringBuilder))
{
//Do the transformation
moXsltTransformation.Transform(oReader, null, oXmlWriter);
}
 
//I'm decended from the MS WebBrowser control, so I can just
//set my DocumentText property to the now populated stringbuilder
this.DocumentText = moStringBuilder.ToString();
}
catch (Exception)
{
this.DocumentText = ERR_HTML;
}
}

One of my big problems is that I don't always practice what I preach. Only two paragraphs and one sub-routine ago did I say (in not so many words), don't bother to cross bridges you haven't come to yet. Some bridges I immediately spotted in the foggy distance convinced me that I may not always have an XmlReader object to pass to the DisplayPrettyXML() routine. Sometimes I'll have a file, other times perhaps and XMLDocument object. So I immediately crossed all the bridges not yet reached, and wrote four overloads for DisplayPrettyXML(). I'll list just one of them here:
    /// <summary>
/// Displays XML contained in a stream using a basic transform.
/// </summary>
/// <param name="strFilePath">The path to an XML file.</param>
/// <remarks></remarks>
public void DisplayPrettyXML(string strFilePath)
{
//to convert the file found at the location into an XmlReader
//and pass it to the overload of DisplayPrettyXML
DisplayPrettyXML(XmlReader.Create(File.OpenRead(strFilePath)));
}

Using the code
To test my new WB component I created a Windows Forms Application, with one form, dropped my WB control onto that form and added five buttons. Each button causes the WB control to do the same thing, but with five different (although they share the same structure) XML files.
        #region cmdFile_Click

public void cmdFile_Click(System.Object sender, System.EventArgs e)
{
//Ask the WebBrowser to display XML from a file
WebBrowser.DisplayPrettyXML("XMLFiles\\MusicLibrarySting.xml");
}
#endregion

#region cmdStream_Click
public void cmdStream_Click(System.Object sender, System.EventArgs e)
{
//Ask the WebBrowser to display XML from a stream
using (FileStream oStream = File.OpenRead("XMLFiles\\MusicLibraryMadonna.xml"))
{
WebBrowser.DisplayPrettyXML(oStream);
}
 
}
#endregion

#region cmdXMLReader_Click
public void cmdXMLReader_Click(System.Object sender, System.EventArgs e)
{
//Ask the WebBrowser to display XML from an XmlReader
using (XmlReader oXmlReader = XmlReader.Create("XMLFiles\\MusicLibraryREM.xml"))
{
WebBrowser.DisplayPrettyXML(oXmlReader);
}
 
}
#endregion

#region cmdXMLDoc_Click

public void cmdXMLDoc_Click(System.Object sender, System.EventArgs e)
{
//Ask the WebBrowser to display XML from an XmlDocument instance
XmlDocument oXmlDocument = new XmlDocument();
oXmlDocument.Load("XMLFiles\\MusicLibrarySeanPaul.xml");
WebBrowser.DisplayPrettyXML(oXmlDocument);
}
#endregion

#region cmdXMLDataDoc_Click
public void cmdXMLDataDoc_Click(System.Object sender, System.EventArgs e)
{
//Ask the WebBrowser to display XML from an XmlDataDocument instance
XmlDataDocument oXmlDataDocument = new XmlDataDocument();
oXmlDataDocument.Load("XMLFiles\\MusicLibraryBeatles.xml");
WebBrowser.DisplayPrettyXML(oXmlDataDocument);
}
#endregion

Points of Interest
    The System.Windows.Forms.WebBrowser control is a good example of a situation where you know of a component that comes close to what you need, but just stops a little short. This can apply to any control and many other .net classes too. If you can set aside some time within your project, it's always a good idea to consider spending it on making library-based functionality that you know you're going to use again. The .net framework lends itself, and supports you in this approach because there are so many aspects of it that you can customise and build upon.


This attachment is hidden for guests. Please log in or register to see it.
This attachment is hidden for guests. Please log in or register to see it.
Attachments:
  • Attachment This attachment is hidden for guests. Please log in or register to see it.
  • Attachment This attachment is hidden for guests. Please log in or register to see it.
  • CE
  • OFFLINE
  • Administrator
  • Posts: 197
  • Karma: 78
The following user(s) said Thank You: fredyvasquez@hotmail.com
CodersEngine
  • Page:
  • 1
Moderators: mnjon
Time to create page: 0.48 seconds