C# XML 目录列表器






4.29/5 (8投票s)
2000年10月22日

256491

6654
生成 XML 格式的目录列表。
这是我使用 .NET alpha 版本编写的一个项目的更新。此版本适用于 .NET Beta 2 版本。
我一直在寻找一个有用的小项目来开始学习 C# 和 .NET 框架。 在我的工作中,我们用 XML 做很多事情,因此我对练习一些 XML 类很感兴趣。 特别是,我想看看 XML 和 ADO+ 如何结合在一起。 结果就是这个项目中的代码。
此代码生成目录中条目的 XML 列表。 XML 可以作为 XML 字符串、W3C DOM 文档或 ADO+ DataSet
返回给调用者。
一个警告。 要编译附加的代码,您需要安装 .NET Framework SDK Beta 2。 您可以在这里 获取 .NET Framework SDK。 请不要向我发送有关安装 SDK 的问题。
以下是 XML 目录列表器的源代码
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; } } }
首先感兴趣的是以下代码
namespace GregHack.XMLStuff.Cs
这表明我正在为我的代码创建一个命名空间。 引用 XMLDirectoryLister
的代码必须包含以下行
using GregHack.XMLStuff.Cs;
大部分工作都在 getXMLUsingDOMCalls()
和 getXMLUsingTextWriterClass()
方法中完成。 它们都通过 .NET 框架的 XmlDocument
类创建一个 W3C 文档,但使用替代方法来实现。 第一种方法使用框架的 XmlDocument
类来添加到和遍历 XML 文档。 第二种方法使用 XMLTextWriter
类来完成相同的事情。
两种实现都使用 C# 的 foreach
语法循环遍历目录中的所有条目
foreach ( FileSystemEntry entry in dir.GetFileSystemEntries() )
XmlDocument
版本使用 AppendChild()
方法将元素插入到文档中,以表示目录中的条目。 XMLTextWriter
版本使用 WriteElementString()
完成相同的事情。
我认为非常酷的是将 XML 转换为 ADO+ DataSet
是多么容易。 getXMLDataset
中的以下代码行就是全部需要的
DataSet ds = null; string strXML = getXMLString( strDirectory ); XmlDataDocument datadoc = new XmlDataDocument(); datadoc.DataSet.ReadXml( new StringReader(strXML) ); ds = datadoc.DataSet; return ds;
ReadXml
方法将解析传入的 XML 并根据 XML 创建数据库架构。
示例项目包含一个命令行测试 .exe 和一个编译为 DLL 的 XMLDirectoryLister
。 它生成以下形式的 XML
<?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>
当调用 getXMLDataset()
方法时,它会返回一个包含两个表 dirlist
和 entry
的 DataSet
。 Entry 具有 7 列, name, created, lastaccess, lastwrite, isfile, isdir, readonly
。 您可以看到 XML 和表之间的关系。
最后一件有趣的事情是类和方法文档。 你会注意到它使用三个正斜杠和一些 XML 标签。 如果你使用这种风格,你可以告诉编译器发出 XML 文档作为输出。 然后它将创建一个 XML 文件,其中包含你放入源代码中的文档。 然后可以将 XML 呈现为 HTML 或其他格式来记录你的源文件。 在你的 Makefile 中使用一个说明符,例如 /doc:XMLDirectoryLister.xml
来发出 XML 文档文件。 示例项目包含编译器发出的 XML 文档。