【问题标题】:C# deserialize xml array of different types into multiple arraysC#将不同类型的xml数组反序列化为多个数组
【发布时间】:2016-05-05 02:22:00
【问题描述】:

我有以下 xml:

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

有没有办法将其反序列化为 C# 对象,以便 AccessibleApplications 和 EligibleApplications 是两个独立的数组?我尝试了以下方法,但出现异常,因为“应用程序”被多次使用。

[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 xml-serialization xmlserializer xml-deserialization


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      以下 sn-p 将输出以下内容:

      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

      abc

      符合条件的申请:

      定义

      zzz

      【讨论】:

        【解决方案3】:

        你可以使用这个类从字符串创建对象,从对象创建字符串和从对象创建字节[]

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

        干杯。

        【讨论】:

          猜你喜欢
          • 2018-01-09
          • 2012-06-04
          • 1970-01-01
          • 2023-04-08
          • 1970-01-01
          • 2012-04-10
          • 1970-01-01
          • 2021-09-08
          • 2015-04-15
          相关资源
          最近更新 更多