65.9K
CodeProject 正在变化。 阅读更多。
Home

C# XML 目录列表器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.29/5 (8投票s)

2000年10月22日

viewsIcon

256491

downloadIcon

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() 方法时,它会返回一个包含两个表 dirlistentryDataSet。 Entry 具有 7 列, name, created, lastaccess, lastwrite, isfile, isdir, readonly。 您可以看到 XML 和表之间的关系。

最后一件有趣的事情是类和方法文档。 你会注意到它使用三个正斜杠和一些 XML 标签。 如果你使用这种风格,你可以告诉编译器发出 XML 文档作为输出。 然后它将创建一个 XML 文件,其中包含你放入源代码中的文档。 然后可以将 XML 呈现为 HTML 或其他格式来记录你的源文件。 在你的 Makefile 中使用一个说明符,例如 /doc:XMLDirectoryLister.xml 来发出 XML 文档文件。 示例项目包含编译器发出的 XML 文档。

© . All rights reserved.