|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
This is an update to a project I wrote using the .NET alpha release. This version works with the .NET Beta 2 release. I was looking for a useful little project to start learning C# and the .NET framework. In my job we do a lot of things with XML so I was interested in exercising some of the XML classes. In particular I wanted to see how XML and ADO+ fit together. The result is the code in this project.
This code generates a list of entries in a directory as XML. The XML can be
returned to the caller as an XML string, a W3C DOM document, or an ADO+ A word of WARNING. To compile the attached code, you need to have the .NET Framework SDK Beta 2 installed which. You can get the .NET Framework SDK here. Please don't send me questions regarding installation of the SDK. Below is the source code for the XML directory lister: using System; using System.IO; using System.Xml; using System.Data; namespace GregHack.XMLStuff.Cs { /// <summary> /// This class generates a list of files in a directory as XML. It can /// return the XML as a string, a W3C DOM document, or a DataSet. I /// wrote this code to learn about the XML capabilities of the framework /// work specifically with the DataSets. /// </summary> public class XMLDirectoryLister { private Boolean m_bUseDOMCalls; /// <summary> /// Constructor /// </summary> /// <param name="bUseDOMCalls">Use W3C DOM calls to build XML?</param> /// <returns>None</returns> public XMLDirectoryLister( Boolean bUseDOMCalls ) { m_bUseDOMCalls = bUseDOMCalls; } /// <summary> /// This method generates a list of files in a directory as XML and /// returns the XML as a string. /// </summary> /// <param name="strDirectory">List files in this directory</param> /// <returns>A XML string with the directory file list</returns> public string getXMLString( string strDirectory ) { string strXML = ""; XmlDocument doc = getXML( strDirectory ); if ( doc != null ) { StringWriter writer = new StringWriter(); doc.Save( writer ); strXML = writer.ToString(); } doc = null; return strXML; } /// <summary> /// This method generates a list of files in a directory as XML and /// returns the XML as a DataSet. /// </summary> /// <param name="strDirectory">List files in this directory</param> /// <returns>A DataSet with the directory file list</returns> public DataSet getXMLDataset( string strDirectory ) { DataSet ds = null; string strXML = getXMLString( strDirectory ); XmlDataDocument datadoc = new XmlDataDocument(); datadoc.DataSet.ReadXml( new StringReader(strXML) ); ds = datadoc.DataSet; return ds; } /// <summary> /// This public method generates a list of files in a directory as XML and /// returns the XML as a W3C DOM document. /// </summary> /// <param name="strDirectory">List files in this directory</param> /// <returns>A W3C DOM docuemnt with the directory file list</returns> public XmlDocument getXMLDocument( string strDirectory ) { return getXML( strDirectory ); } private XmlDocument getXML( string strDirectory ) { XmlDocument xmlDoc; if ( m_bUseDOMCalls ) xmlDoc = getXMLUsingDOMCalls( strDirectory ); else xmlDoc = getXMLUsingTextWriterClass( strDirectory ); return xmlDoc; } /// <summary> /// This private method generates a list of files in a directory as XML and /// returns the XML as a W3C DOM document using the DOM calls. /// </summary> /// <param name="strDirectory">List files in this directory</param> /// <returns>A W3C DOM docuemnt with the directory file list</returns> private XmlDocument getXMLUsingDOMCalls( string strDirectory ) { // Create the document. XmlDocument doc = new XmlDocument(); // Insert the xml processing instruction and the root node XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "", "yes"); doc.PrependChild ( dec ); // Add the root element XmlElement nodeElem = doc.CreateElement( "dirlist" ); doc.AppendChild( nodeElem ); Boolean bFirst = true; // Process the directory list DirectoryInfo dir = new DirectoryInfo( strDirectory ); foreach ( FileSystemInfo entry in dir.GetFileSystemInfos() ) { if ( bFirst == true ) { // If we haven't added any elements yet, go ahead and add a text element which // contains the full directory path. XmlElement root = doc.DocumentElement; String strFullName = entry.FullName; String strFileName = entry.Name; String strDir = strFullName.Substring( 0, strFullName.Length - strFileName.Length ); root.SetAttribute ("dir", strDir ); bFirst = false; } // Add a new text node with a tag entry. There will be one added per // item encountered in the directory. XmlElement elem = doc.CreateElement("entry"); doc.DocumentElement.AppendChild(elem); // Write out the things we are interested in about this entry in the // directory. addTextElement( doc, elem, "name", entry.Name ); addTextElement( doc, elem, "created", entry.CreationTime.ToString() ); addTextElement( doc, elem, "lastaccess", entry.LastAccessTime.ToString() ); addTextElement( doc, elem, "lastwrite", entry.LastWriteTime.ToString() ); addTextElement( doc, elem, "isfile", ( (entry.Attributes & FileAttributes.Directory) > 0 ) ? "False" : "True" ); addTextElement( doc, elem, "isdir", ( (entry.Attributes & FileAttributes.Directory) > 0 ) ? "True" : "False" ); addTextElement( doc, elem, "readonly", ( (entry.Attributes & FileAttributes.ReadOnly) > 0 ) ? "True" : "False" ); } return doc; } /// <summary> /// This private method adds a text element to the XML document as the last /// child of the current element. /// </summary> /// <param name="doc">The XML document</param> /// <param name="nodeParent">Parent of the node we are adding</param> /// <param name="strTag">The tag of the element to add</param> /// <param name="strValue">The text value of the new element</param> private void addTextElement( XmlDocument doc, XmlElement nodeParent, string strTag, string strValue ) { XmlElement nodeElem = doc.CreateElement( strTag ); XmlText nodeText = doc.CreateTextNode( strValue ); nodeParent.AppendChild( nodeElem ); nodeElem.AppendChild( nodeText ); } /// <summary> /// This private method generates a list of files in a directory as XML and /// returns the XML as a W3C DOM document using the XmlTextWriter class. /// </summary> /// <param name="strDirectory">List files in this directory</param> /// <returns>A W3C DOM docuemnt with the directory file list</returns> private XmlDocument getXMLUsingTextWriterClass( string strDirectory ) { StringWriter writerString = new StringWriter(); XmlTextWriter writer = new XmlTextWriter( writerString ); writer.WriteStartDocument(true); Boolean bFirst = true; // Process the directory list DirectoryInfo dir = new DirectoryInfo( strDirectory ); foreach ( FileSystemInfo entry in dir.GetFileSystemInfos() ) { if ( bFirst == true ) { // If we haven't added any elements yet, go ahead and add a text element which // contains the full directory path. writer.WriteStartElement( "dirlist", "" ); String strFullName = entry.FullName; String strFileName = entry.Name; String strDir = strFullName.Substring( 0, strFullName.Length - strFileName.Length ); writer.WriteAttributeString( "dir", strDir ); bFirst = false; } // Add a new text node with a tag entry. There will be one added per // item encountered in the directory. writer.WriteStartElement( "entry", "" ); // Write out the things we are interested in about this entry in the // directory. writer.WriteElementString( "name", entry.Name ); writer.WriteElementString( "created", entry.CreationTime.ToString() ); writer.WriteElementString( "lastaccess", entry.LastAccessTime.ToString() ); writer.WriteElementString( "lastwrite", entry.LastWriteTime.ToString() ); writer.WriteElementString( "isfile", ( (entry.Attributes & FileAttributes.Directory) > 0 ) ? "False" : "True" ); writer.WriteElementString( "isdir", ( (entry.Attributes & FileAttributes.Directory) > 0 ) ? "True" : "False" ); writer.WriteElementString( "readonly", ( (entry.Attributes & FileAttributes.ReadOnly) > 0 ) ? "True" : "False" ); writer.WriteEndElement(); // entry } writer.WriteEndElement(); // dirlist writer.WriteEndDocument(); string strXML = writerString.ToString(); StringReader reader = new StringReader( strXML ); XmlDocument doc = new XmlDocument(); doc.Load( reader ); return doc; } } } The first thing of interest is the following code: namespace GregHack.XMLStuff.Cs
This says that I am creating a namespace for my code. Code that references the
using GregHack.XMLStuff.Cs;
The meat of the work is done in the
Both implementations loop through all of the entries in the directory using the
foreach ( FileSystemEntry entry in dir.GetFileSystemEntries() )
The
Something that I thought was pretty cool is how easy it is to translate XML into
an ADO+ DataSet ds = null; string strXML = getXMLString( strDirectory ); XmlDataDocument datadoc = new XmlDataDocument(); datadoc.DataSet.ReadXml( new StringReader(strXML) ); ds = datadoc.DataSet; return ds;
The The sample project contains a command line test .exe and a the <?xml version='1.0' ?> <dirlist dir="C:\anet\XML Directory\"> <entry> <name>XMLDirectoryLister.bak</name> <created>9/21/2000 21:13:34</created> <lastaccess>9/21/2000 00:00:00</lastaccess> <lastwrite>9/21/2000 21:53:54</lastwrite> <isfile>True</isfile> <isdir>False</isdir> <readonly>False</readonly> </entry> <entry> <name>XMLDirectoryLister.dll</name> <created>9/21/2000 19:19:13</created> <lastaccess>9/21/2000 00:00:00</lastaccess> <lastwrite>9/21/2000 21:12:20</lastwrite> <isfile>True</isfile> <isdir>False</isdir> <readonly>False</readonly> </entry> </dirlist>
When the
One last thing of interest is the class and method documentation. You'll notice it
uses three forward slashes and some XML tags. If
you use this style you can tell the compiler to emit XML documentation as output. It
will then create and XML file containing the documentation you put in your source file.
The XML could then be rendered as HTML or some other format to document you source. Use
a specifier in your makefile such as
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||