C# 将不同类型的 xml 数组反序列化为多个数组

本文关键字:数组 反序列化 xml 同类型 | 更新日期: 2023-09-27 18:32:08

我有以下xml:

<Applications>
    <AccessibleApplication></AccessibleApplication>
    <AccessibleApplication></AccessibleApplication>
    <EligibleApplication></EligibleApplication>
    <EligibleApplication></EligibleApplication>
</Applications>

有没有办法将其反序列化为 C# 对象,以便可访问应用程序和合格应用程序是两个单独的数组?我尝试了以下内容,但出现异常,因为"应用程序"被多次使用。

[XmlArray("Applications")]
[XmlArrayItem("AccessibleApplication")]
public List<Application> AccessibleApplications { get; set; }
[XmlArray("Applications")]
[XmlArrayItem("EligibleApplication")]
public List<Application> EligibleApplications { get; set; }

例外情况是:来自命名空间"的 XML 元素"应用程序"已存在于当前作用域中。使用 XML 属性为元素指定另一个 XML 名称或命名空间。

这可能做到吗?

谢谢!

编辑:我忘了提到我不想仅仅为了为两个数组提供一个容器对象而拥有一个"应用程序"类。我有几种这样的情况,我不希望这些类的混乱,它们的唯一目的是拆分两个相同类型的数组。

我希望能够使用某种标签(如 [XmlArrayItem="Application/AccessibleApplication")将两个数组反序列化为外部对象,而无需创建"应用程序"类。

C# 将不同类型的 xml 数组反序列化为多个数组

我找到了一个相当巧妙的方法,首先创建一个这样的类:

using System.Xml.Serialization;
[XmlRoot]
public class Applications
{
    [XmlElement]
    public string[] AccessibleApplication;
    [XmlElement]
    public string[] EligibleApplication;
}

请注意元素是如何成为单个数组的。现在使用这个类(我将我的 XML 放在一个单独的文件中,因此是 XmlDocument 类)。

var doc = new XmlDocument();
doc.Load("../../Apps.xml");
var serializer = new XmlSerializer(typeof(Applications));
Applications result;
using (TextReader reader = new StringReader(doc.InnerXml))
{
    result = (Applications)serializer.Deserialize(reader);
}

现在为了证明这是有效的,您可以将所有这些写入控制台应用程序,并执行 foreach 以打印数组中的所有值,如下所示:

foreach (var app in result.AccessibleApplication)
{
    Console.WriteLine(app);
}
foreach (var app in result.EligibleApplication)
{
    Console.WriteLine(app);
}

可以使用 XmlElement 属性反序列化为不同的列表:

public class Applications
{
    [XmlElement("AccessibleApplication")]
    public List<Application> AccessibleApplications { get; set; }
    [XmlElement("EligibleApplication")]
    public List<Application> EligibleApplications { get; set; }
}
public class Application
{
    [XmlText]
    public string Value { get; set; }
}

因此,对于示例 XML:

<Applications>
    <AccessibleApplication>xyz</AccessibleApplication>
    <AccessibleApplication>abc</AccessibleApplication>
    <EligibleApplication>def</EligibleApplication>
    <EligibleApplication>zzz</EligibleApplication>
</Applications>

以下代码片段将输出以下内容:

using (var reader = new StreamReader("XMLFile1.xml"))
{
    var serializer = new XmlSerializer(typeof(Applications));
    var applications = (Applications)serializer.Deserialize(reader);
    Console.WriteLine("AccessibleApplications:");
    foreach (var app in applications.AccessibleApplications)
    {
        Console.WriteLine(app.Value);
    }
    Console.WriteLine();
    Console.WriteLine("EligibleApplications:");
    foreach (var app in applications.EligibleApplications)
    {
        Console.WriteLine(app.Value);
    }
}

输出:

可访问的应用程序:

xyz

美国广播公司

合格申请:

定义

兹兹

您可以使用此类从字符串创建对象,从对象创建字符串以及从对象创建字节 []

字符串到对象

var applicationObject = new XmlSerializerHelper<Applications>().StringToObject(xmlString);

对象到字符串

var xmlString = new XmlSerializerHelper<Applications>().ObjectToString(applicationObject);

ObjectToByteArray

var byteArray = new XmlSerializerHelper<Applications>().ObjectToByteArray(applicationObject);

XmlSerializerHelper:

namespace StackOverflow
{
    public class XmlSerializerHelper<T> where T : class
    {
        private readonly XmlSerializer _serializer;
        public XmlSerializerHelper()
        {
            _serializer = new XmlSerializer(typeof(T));
        }
        public T ToObject(string xml)
        {
            return (T)_serializer.Deserialize(new StringReader(xml));
        }
        public string ToString(T obj, string encoding)
        {
            using (var memoryStream = new MemoryStream())
            {
                _serializer.Serialize(memoryStream, obj);
                return Encoding.GetEncoding(encoding).GetString(memoryStream.ToArray());
            }
        }
        public byte[] ToByteArray(T obj, Encoding encoding = null)
        {
            var settings = GetSettings(encoding);
            using (var memoryStream = new MemoryStream())
            {
                using (var writer = XmlWriter.Create(memoryStream, settings))
                {
                    _serializer.Serialize(writer, obj);
                }
                return memoryStream.ToArray();
            }
        }
        private XmlWriterSettings GetSettings(Encoding encoding)
        {
            return new XmlWriterSettings
            {
                Encoding = encoding ?? Encoding.GetEncoding("ISO-8859-1"),
                Indent = true,
                IndentChars = "'t",
                NewLineChars = Environment.NewLine,
                ConformanceLevel = ConformanceLevel.Document
            };
        }
    }
 }

您的班级:

[XmlRoot]
public class Applications
{
    [XmlElement("AccessibleApplication")]
    public string[] AccessibleApplication { get; set; }
    [XmlElement("EligibleApplication")]
    public string[] EligibleApplication { get; set; }
}

[XmlRoot]
public class Applications
{
    [XmlElement("AccessibleApplication")]
    public List<string> AccessibleApplication { get; set; }
    [XmlElement("EligibleApplication")]
    public List<string> EligibleApplication { get; set; }
}

干杯。