Scott Hanselman

XmlTextReader more and more

March 04, 2006 Comment on this post [9] Posted in XML | Web Services
Sponsored By

Random thought: I like the whole XmlReader philosophy. I use it much more often than XmlDocument. I haven't made an XmlDocument in a while. Every once in a while an XmlDocument shows up when you need an XmlNode for some SOAP stuff, but for the most part, I like XmlReaders.

Someone wanted a chunk of code that grabbed RSS Enclosures from a feed. They didn't care about the content, they just wanted the enclosures' attributes. Here's what I sent them 2 mins later.

Sure this code could have been done with XmlDocument.SelectNodes (and I'm sure one of you will show me how) but without getting to much into premature optimization, I know that using an XmlReader will always give me better performance. Always. If use it for little one-off stuff like this, I know when I need real performance for a real app, the usage will be fresh in my mind.

using System;

using System.Xml;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            XmlTextReader tr =
               new XmlTextReader("http://feeds.feedburner.com/ScottHanselman");

            object enclosure = tr.NameTable.Add("enclosure");

            while (tr.Read())

            {

                if (tr.NodeType == XmlNodeType.Element &&

                    Object.ReferenceEquals(tr.LocalName, enclosure))

                {

                    while (tr.MoveToNextAttribute())

                    {

                        Console.WriteLine(String.Format("{0}:{1}",
                           tr.LocalName, tr.Value));

                    }

                }

 

            }

        }

    }

}

Now playing: Rent - Rent

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
March 04, 2006 17:18
I agree that your implementation will always be faster, but here is the XmlDocument version anyway ;-) Anyway, it is always good to know more than one way to solve any problem:

XmlDocument doc = new XmlDocument();
doc.Load("http://feeds.feedburner.com/ScottHanselman");

foreach (XmlNode node in doc.SelectNodes("//enclosure"))
{
foreach (XmlAttribute attr in node.Attributes)
{
Console.WriteLine(string.Format("{0}:{1}", attr.Name, attr.Value));
}
}
March 04, 2006 23:02
Hi Scott,

I tried posting a comment on your "XmlReader More and more" post but the comment spammer test image wouldn't display. I only saw the red X for broken image link. Anyway, I wanted to let you know about another way to do this is kind of neat. This is what I was going to post in the comment:

For a really quick one off, try this from the beta Monad (Microsoft Command Shell - yeah right from the command prompt):

$url = "http://feeds.feedburner.com/ScottHanselman"
$feed = [xml](new-object System.Net.WebClient).DownloadString($url)
$feed.GetElementsByTagName("enclosure") | format-list


url : http://perseus.franklins.net/hanselminutes_0008_lo.wma
type : audio/x-ms-wma
length : 8902435

url : http://perseus.franklins.net/hanselminutes_0006_lo.wma
type : audio/x-ms-wma
length : 7835219

Download Monad (and one heck of a .NET based, CLI scripting environment) from here:
http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

--
Keith Hill
MVP for the Microsoft Command Shell
March 05, 2006 4:21
It's the same thing with the DataReader. It will always give better performance than a DataSet. It's obvious, a DataSet uses a DataReader internally to populate it.

Isn't that the same case with an XmlDocument, that it uses an XmlReader to populate the document?
March 06, 2006 15:28
I don't understand what the nametable lookup stuff is doing. Can you Explain?

cheers
bg
March 06, 2006 21:13
Yeah I am a bit puzzled on how your using the NameTable there, I did some debugging on it and is this how you are telling if the node element is a url element? Not sure exactly whats going on there, I to would like an explanation. I have never done anything like that with the XmlReader, could explain the benefits of doing it like this versus a more known method?

Thanks Scott!!
March 06, 2006 23:08
I go 100% in the other direction. I much prefer to use XPATH as I find it easier to see what the code is doing in a single expression like:

//Foo[1]/Bar[@val = 'gerrard']

rather than ten or 15 lines of procedural code.

Perf is great, but in most of my apps simple maintanability and easy ramp up are way more important that getting every single drop of speed...
March 07, 2006 10:42
Obviously a read-only object (XmlReader) would be faster than a multi-purpose object (XmlDocument) which allows you in addition to reading, also manipulating the object.

For what you are using it, XmlReader is perfect, however, I believe that if you are already using a standard XML ATOM/RSS/etc... you should be using the whole package of standards that accompany it as much as is benefical, in this case I would use XPath to query the xml doc, you can use XmlDocument or XPathReader (http://workspaces.gotdotnet.com/xpathreader also http://blogs.msdn.com/mfussell/archive/2004/05/12/130312.aspx and http://msdn.microsoft.com/xml/default.aspx?pull=/library/en-us/dnexxml/html/xml05192004.asp) which is an implementation of XmlReader, that supports XPath. Using XPath is a no-brainer for anyone that knows a bit of XML, and I think, makes the code easier to understand.
March 08, 2006 7:46
XmlTextReader, Nametable and object-equality checks. yup, that's pretty much how SharpReader does it as well :-)
March 10, 2006 1:33
>XmlDocument shows up when you need an XmlNode for some SOAP stuff

If that's the case, you probably missed by post from about two years ago: http://clariusconsulting.net/blogs/kzu/archive/2004/05/31/241.aspx.

It's NEVER necessary to load an XML document for web services ;-)

We now even provide a factory method so that you can return strongly typed objects that need to be exposed only as XmlNodes on the client end by means of XmlSerializer:

public static XmlNode Create(object value)
{
return new ObjectNode(value);
}

All without XmlDocuments whatsoever... enjoy buddy!

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.