【问题标题】:Reading large XML files with C#使用 C# 读取大型 XML 文件
【发布时间】:2015-12-23 07:32:18
【问题描述】:

我想知道如何从桌面读取 XML 文件并将其放入字符串中?

这是我的 XML:

<smallusers>
    <user id="1">
        <name>John</name>
        <motto>I am john, who are you?</motto>
    </user>
    <user id="2">
        <name>Peter</name>
        <motto>Hello everyone!</motto>
    </user>
</smallusers>
<bigusers>
    <user id="3">
        <name>Barry</name>
        <motto>Earth is awesome</motto>
    </user>
</bigusers>

我想存储每个用户,但仍然检测他们的大小,有没有办法做到这一点?

在你降级之前,你可能想检查一下谷歌,因为我做了研究,但一无所获。

【问题讨论】:

  • 我不知道那是什么?
  • 就像我已经解释的那样,我找不到任何关于使用多个根执行此操作的信息。
  • “从我的桌面读取一个xml文件并放入一个字符串”是什么意思???
  • 可能是一个字符串列表?我只是想把它存储在某个地方。
  • XML Error: There are multiple root elements 的可能重复项 - 只是因为您提到“我找不到任何关于使用多个根执行此操作的信息。”

标签: c# xml serialization deserialization


【解决方案1】:

“在你降级之前,你可能想检查一下谷歌,因为我 做了研究,但一无所获”

您什么也没找到,因为您不知道要搜索什么,而且您的 XML 无效,您需要将其括在 rootElement 中。然后,您需要做的第一件事是从桌面读取此文件(如果存在)。

您可以在那时检查大小并确定它是否“太大”,即使这并不重要。我非常怀疑您的 XML 文件的大小会超过 5 GB。如果是,那么您需要一个替代方案,.Net 程序中的单个对象可能不会超过 2GB,您可以做的最好的事情是 64 位机器上的 1,073,741,823。

对于非常大的 XML 文件,任何超过 1.0 GB 的文件,如 Jon Skeet here 所述,结合 XmlReader 和 LINQ:

如果你的文档特别大,你可以结合 XmlReader 和 LINQ to XML 通过从 XmlReader 为您的每个 以流的方式“外部”元素:这可以让你做大部分的 LINQ to XML 中的转换工作,但仍然只需要一小部分 内存中的文档。

对于小型 XML 文件,任何 1.0 GB 或更低的文件都坚持使用 DOM,如下所示。

话虽如此,您需要了解SerializationDeserialization 的含义。

Serialize 将对象实例转换为 XML 文档。

Deserialize 将 XML 文档转换为对象实例。

除了 XML,您还可以使用 JSON、二进制等。

在您的情况下,可以将Deserialize 这个XML 文档重新转换为对象,以便您在代码中使用。

首先修复 XML 并给它一个 Root。

<?xml version="1.0" encoding="UTF-8"?>
<DataRoot>
    <smallusers>
        <user id="1">
            <name>John</name>
            <motto>I am john, who are you?</motto>
        </user>
        <user id="2">
            <name>Peter</name>
            <motto>Hello everyone!</motto>
        </user>
    </smallusers>
    <bigusers>
        <user id="3">
            <name>Barry</name>
            <motto>Earth is awesome</motto>
        </user>
    </bigusers>
</DataRoot>

然后在 C# 中创建根类,您可以直接在 Visual Studio 2012+ 中通过复制您的 XML 并转到 Edit - Paste Special 来生成它,但我喜欢使用:XML to C# Class Generator

这是为 XML 生成 C# 根类后代码的样子,希望它可以帮助您更好地理解它。

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    public class Program
    {
        [XmlRoot(ElementName = "user")]
        public class User
        {
            [XmlElement(ElementName = "name")]
            public string Name { get; set; }
            [XmlElement(ElementName = "motto")]
            public string Motto { get; set; }
            [XmlAttribute(AttributeName = "id")]
            public string Id { get; set; }
        }

        [XmlRoot(ElementName = "smallusers")]
        public class Smallusers
        {
            [XmlElement(ElementName = "user")]
            public List<User> User { get; set; }
        }

        [XmlRoot(ElementName = "bigusers")]
        public class Bigusers
        {
            [XmlElement(ElementName = "user")]
            public User User { get; set; }
        }

        [XmlRoot(ElementName = "DataRoot")]
        public class DataRoot
        {
            [XmlElement(ElementName = "smallusers")]
            public Smallusers Smallusers { get; set; }
            [XmlElement(ElementName = "bigusers")]
            public Bigusers Bigusers { get; set; }
        }


        static void Main(string[] args)
        {
            string testXMLData = @"<DataRoot><smallusers><user id=""1""><name>John</name><motto>I am john, who are you?</motto></user><user id=""2""><name>Peter</name><motto>Hello everyone!</motto></user></smallusers><bigusers><user id=""3""><name>Barry</name><motto>Earth is awesome</motto></user></bigusers></DataRoot>";

            var fileXmlData = File.ReadAllText(@"C:\XMLFile.xml");
            var deserializedObject = DeserializeFromXML(fileXmlData);
            var serializedToXML = SerializeToXml(deserializedObject);

            //I want to store each user, but still detect if their small or big, is there a way to do this?
            foreach (var smallUser in deserializedObject.Smallusers.User)
            {
              //Iterating your collection of Small users? 
              //Do what you need here with `smalluser`.
              var name = smallUser.Name; //Example...
            }


            Console.WriteLine(serializedToXML);
            Console.ReadKey();
        }

        public static string SerializeToXml(DataRoot DataObject)
        {
            var xsSubmit = new XmlSerializer(typeof(DataRoot));

            using (var sw = new StringWriter())
            {
                using (var writer = XmlWriter.Create(sw))
                {
                    xsSubmit.Serialize(writer, DataObject);
                    var data = sw.ToString();
                    writer.Flush();
                    writer.Close();
                    sw.Flush();
                    sw.Close();
                    return data;
                }
            }
        }

        public static DataRoot DeserializeFromXML(string xml)
        {
            var xsExpirations = new XmlSerializer(typeof(DataRoot));
            DataRoot rootDataObj = null;
            using (TextReader reader = new StringReader(xml))
            {
                rootDataObj = (DataRoot)xsExpirations.Deserialize(reader);
                reader.Close();
            }
            return rootDataObj;
        }
    }
}

【讨论】:

  • 在某些情况下,您必须读取大型 xml 文件。考虑分析不同技术领域的传播文化。您可以download dumps from relevant stackexchange sites 提取帖子和cmets。天真地全押是行不通的(stackoverflow 上的 14GiB Comments.xml)。然后继续谷歌,找到相关的问题,如 Reading large XML files with C# 并感到失望。您的 我非常怀疑您的 xml 文件大小会超过 5 GB。 是一记重拳。它根本不适用于使用 C# 读取大型 XML 文件
  • @mbx 很公平,我继续更新了答案。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多