【问题标题】:Issues Deserializing Xml in C#在 C# 中反序列化 Xml 的问题
【发布时间】:2019-07-11 17:10:55
【问题描述】:

我正在按照here 提供的教程反序列化嵌入的 xml 文档。

我的 Xml 文档:

<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfAgency xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <DbAgencyDefinition>
    <Name>RTD</Name>
    <Country>USA</Country>
    <City>Denver</City>
    <State>CO</State>
    <GtfsZipUrlDirectory>http://www.address.com/etc/</GtfsZipUrlDirectory>
    <GtfsZipUrlFileName>file_name.zip</GtfsZipUrlFileName>
  </DbAgencyDefinition>
</ArrayOfAgency>

我要反序列化到的类:

public class DbAgencyDefinition
    {
        public string Name { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
        public string GtfsZipUrlDirectory { get; set; }
        public string GtfsZipUrlFileName { get; set; }
        public string State { get; set; }
    }

试图将 XML 反序列化为 DbAgencyDefinition 列表的代码:

var assembly = IntrospectionExtensions.GetTypeInfo(typeof(DbAgencyDefinition)).Assembly;
            Stream stream = assembly.GetManifestResourceStream("MyNamespace.Resources.xml.AgencyDefinitions.xml");
            var agencies = new List<DbAgencyDefinition>();
            using (var reader = new StreamReader(stream))
            {
                var serializer = new XmlSerializer(typeof(List<DbAgencyDefinition>));
                agencies = (List<DbAgencyDefinition>)serializer.Deserialize(reader);
            }

我得到的错误是:

System.Exception: There is an error in XML document. <ArrayOfAgency xmlns=''> was not expected

我已经用 XML 尝试了一百万次,将类标记为可序列化,但它总是返回这个错误。我查看了教程提供的代码示例,但不知道为什么会出现此错误。

【问题讨论】:

    标签: c# android xml xamarin


    【解决方案1】:

    VS for Windows,也许在 Mac 上也有一个特殊的工具,可以将复制的 Xml 转换为自动生成的类。现在,它并不完美,但如果您使用 Xml 文件,它会生成几个类似的类:

    public class ArrayOfAgency
    {
        public ArrayOfAgencyDbAgencyDefinition DbAgencyDefinition { get; set; }
    }
    
    public class ArrayOfAgencyDbAgencyDefinition
    {
        public string Name { get; set; }
        public string Country { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string GtfsZipUrlDirectory { get; set; }
        public string GtfsZipUrlFileName { get; set; }
    }
    

    您可能会注意到ArrayOfAgency 被确定为持有DbAgencyDefinition 的类,这就是为什么它在尝试将其直接反序列化为List&lt;DbAgencyDefinition&gt; 时抛出错误的原因。序列化程序所期望的类型和内容并不完全相同。

    var serializer = new XmlSerializer(typeof(ArrayOfAgency));
    var agencies = ((ArrayOfAgency)serializer.Deserialize(reader)).DbAgencyDefinition;
    

    另外,正如我所提到的,自动生成可能并不完美,因为如果 Xml 中可能存在多个 DbAgencyDefinitionArrayOfAgency 可能需要保存一个数组而不是直接类。

    public class ArrayOfAgency
    {
        public ArrayOfAgencyDbAgencyDefinition[] DbAgencyDefinition { get; set; }
    }
    

    如果您需要有关 Xml 序列化的更多帮助或信息,请查看docs

    【讨论】:

      【解决方案2】:

      尝试以下:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Xml;
      using System.Xml.Serialization;
      using System.IO;
      
      namespace ConsoleApplication120
      {
          class Program
          {
              const string FILENAME = @"c:\temp\test.xml";
              static void Main(string[] args)
              {
                  using (var reader = new StreamReader(FILENAME, Encoding.UTF8))
                  {
                      var serializer = new XmlSerializer(typeof(ArrayOfAgency));
                      ArrayOfAgency agencies = (ArrayOfAgency)serializer.Deserialize(reader);
                  }
      
              }
          }
          public class ArrayOfAgency
          {
              public DbAgencyDefinition DbAgencyDefinition { get; set; }
          }
          public class DbAgencyDefinition
          {
              public string Name { get; set; }
              public string City { get; set; }
              public string Country { get; set; }
              public string GtfsZipUrlDirectory { get; set; }
              public string GtfsZipUrlFileName { get; set; }
              public string State { get; set; }
          }
      
      }
      

      【讨论】:

      • 你能解释一下你提出的解决方案与 OP 的代码相比吗?
      • 这很有帮助,但假设 XML 中有多个 DbAgencyDefinition 节点? ArrayOfAgency 类应该有 public List 吗?我试过了,它没有出错,但也没有返回任何东西。
      • 使用多个 DbAgencyDefinition 节点,只需将属性的返回类型更改为数组即可。公共 DbAgencyDefinition[] DbAgencyDefinition { 获取;放;我建议选择一个不同的名称,这只是令人困惑。
      • xml 根级别的数组被认为格式不正确。 Net 序列化方法会给出异常。要在根级别处理数组,您需要使用带有选项集片段的 XmlReader 手动反序列化。
      猜你喜欢
      • 2021-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多