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

时间:2016-01-27 22:14:17

标签: c# xml xml-serialization xmlserializer xml-deserialization

我有以下xml:

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

有没有办法将其反序列化为C#对象,以便AccessibleApplications和EligibleApplications是两个独立的数组?我尝试了以下但是得到了一个例外,因为&#34;应用程序&#34;不止一次使用。

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

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

例外是: XML元素&#39;应用程序&#39;来自命名空间&#39;&#39;已存在于当前范围内。使用XML属性为元素指定另一个XML名称或命名空间。

这可能吗?

谢谢!

编辑:我忘了提到我不想要一个&#34;应用程序&#34; class只是为了为两个数组提供容器对象。我有几种这样的情况,我不想要这些类的混乱,其唯一目的是拆分两个相同类型的数组。

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

3 个答案:

答案 0 :(得分:0)

我找到了一个相当简洁的方法来做这个,先做一个这样的课:

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);
}

答案 1 :(得分:0)

您可以使用 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);
    }
}

输出:

  

AccessibleApplications:

     

xyz

     

ABC

     

符合条件的申请:

     

def

     

ZZZ

答案 2 :(得分:0)

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

<强> StringToObject

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

<强>的ObjectToString

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; }
}

干杯。