使用C#读取大型XML文件

Jos*_*low 0 c# xml serialization deserialization

我想知道如何从桌面读取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>
Run Code Online (Sandbox Code Playgroud)

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

在你降低这一点之前,你可能想检查谷歌,因为我做了研究,但没有发现任何东西.

Day*_*yan 8

"在你低估这个之前,你可能想检查谷歌,因为我做了研究,但没有找到任何结果"

你找不到任何东西,因为你不知道你在搜索什么,你的XML也是无效的,你需要把它括在一个rootElement.然后,您需要做的第一件事是从桌面读取该文件(如果存在).

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

对于非常大的XML文件,任何超过1.0 GB,由乔恩斯基特陈述结合的XmlReader和LINQ 在这里:

如果您的文档特别大,您可以通过XmlReader以流方式为每个"外部"元素创建一个XElement来将XmlReader和LINQ结合到XML:这使您可以在LINQ to XML中完成大部分转换工作,但是在任何时候,仍然只需要内存中的一小部分文档.

对于小型XML文件,任何1.0 GB或更低的文件都会粘在DOM上,如下所示.

话虽如此,你需要的是学习什么SerializationDeserialization意思.

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

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

您也可以使用JSON,二进制等代替XML.

在您的情况下,可以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>
Run Code Online (Sandbox Code Playgroud)

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

以下是为XML生成C#Root类后代码的样子,希望它能帮助您更好地理解它.

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)