如何将文件夹中的所有 Xml 文件加载到 XmlDocument

问题描述 投票:0回答:2

使用下面的代码,我可以在 XmlDocument xWorkload 中加载一个 Xml 文件。

XmlDocument xWorkload = new XmlDocument();

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            var outputxml = new StringBuilder(string.Empty);

            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); 
            dlg.FileName = "demo"; // Default file name
            dlg.DefaultExt = ".xml"; // Default file extension
            dlg.Filter = "Xml documents (.xml)|*.xml";  // Filter files by extension


            var result = dlg.ShowDialog();  //Opens the dialog box
            if (result == true)
            {
                xWorkload.Load(dlg.FileName);
                string Path = dlg.FileName.Replace(dlg.SafeFileName, "");
            }
        }

假设,一个文件夹中有多个Xml文件,而我想将所有的Xml文件加载到xWorkload中,并将这些xml文件存储在一个字符串中 我该怎么做?可以只使用 XmlDocument(不是 Linq)在 wpf 中完成吗?请建议

c# xml wpf xmldocument
2个回答
8
投票

您可以使用

FolderBrowserDialog
选择Xml文件根目录,然后:

FolderBrowserDialog fd = new FolderBrowserDialog();
DialogResult result = fd.ShowDialog();

if(result == DialogResult.OK)
{
    string[] files = Directory.GetFiles(fd.SelectedPath)
                              .Where(p => p.EndsWith(".xml"))
                              .ToArray();
    foreach(var path in files)
    {  
        XDocument xDoc = XDocument.Load(path);
        // read Xml file
    }
}

0
投票
        private async Task<User_Directory> Directory_Dissasembly_Operation(string root_directory_path)
        {

            User_Directory current_directory = new User_Directory();

            current_directory.directory_name = System.IO.Path.GetFileName(root_directory_path);





            StringBuilder string_builder = new StringBuilder(root_directory_path);



            IEnumerator files_enumerator = System.IO.Directory.GetFiles(string_builder.ToString()).GetEnumerator();

            while(files_enumerator.MoveNext() == true)
            {
                string_builder.Clear();
                string_builder.Append((string)files_enumerator.Current);

                System.IO.FileInfo f_info = new System.IO.FileInfo(string_builder.ToString());

                if(f_info.Extension == ".xml")
                {
                    System.Threading.Thread.Sleep(10);

                    Tuple<string, byte[]> current_item = new Tuple<string, byte[]>(f_info.FullName, await System.IO.File.ReadAllBytesAsync(string_builder.ToString()));
                    current_directory.files_list.Add(current_item);
                }
            }

            files_enumerator.Reset();





            IEnumerator directories_enumerator = System.IO.Directory.GetDirectories(root_directory_path).GetEnumerator();

            while(directories_enumerator.MoveNext() == true)
            {
                string_builder.Clear();
                string_builder.Append((string)directories_enumerator.Current);

                System.Threading.Thread.Sleep(10);

                current_directory.sub_directories.Add(await Directory_Dissasembly_Operation(string_builder.ToString()));
            }

            directories_enumerator.Reset();



            string_builder.Clear();

            return current_directory;
        }

鉴于 F 是总文件数,D 是目录总数,因此该算法的时间复杂度为 O(F * D),因为它循环 F 次目录中的文件,D 次导致O(F * D).




时间复杂度:O(F * D)



空间复杂度:O(N)







说明



该算法使用两个循环,查看作为参数传递给方法的目录路径中的文件,以及一个循环遍历作为参数传递给方法的目录路径的子目录。如果文件有

.xml
扩展名,文件名和二进制值存储在每个文件的元组中,并且这些元组存储在类对象内的列表中。当当前目录路径中的所有文件都被提取出来后,第二个循环遍历当前目录的子目录,并通过在循环的每次迭代中将路径传递到当前子目录来进行递归。这种情况会发生,直到所有子目录都被枚举通过。该方法返回
User_Directory
类的一个实例,该实例将被添加到
User_Directory
类中存储
User_Directory
类对象的列表中。
IEnumerable
对象用于遍历文件和目录数组,因为它比传统迭代消耗更少的内存资源,因为每个元素都是一个一个加载的,而不会创建不必要的对象的额外副本迭代。
Thread.Sleep(10)
方法使线程休眠 10 毫秒,以便通过将每个循环的迭代次数限制为每 10 毫秒一次来为运行时管理内存资源和减轻 CPU 使用率提供时间;




[注意]


这种方法对于大文件和/或目录不是最优的,因为内容将加载到动态内存(RAM)中,如果目录和/或文件大于可用内存量,操作系统将抛出“内存不足”异常。最好的方法是一个一个地加载文件,对它们执行所需的过程,然后从内存中释放它们。您可以修改我提供的算法以尽可能适合您的情况。

© www.soinside.com 2019 - 2024. All rights reserved.