在 Xamarin 中反序列化 XML

Posted

技术标签:

【中文标题】在 Xamarin 中反序列化 XML【英文标题】:Deserialize XML in Xamarin 【发布时间】:2017-06-21 18:34:25 【问题描述】:

我正在尝试反序列化一个名为 CSound 的类

public class CSound
 
    public string id  get; set; 
    public string name  get; set; 
    public string file  get; set; 
    public string fav  get; set; 

..来自这个 XML

<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfSounds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <CSound>
    <id>1</id>
    <name>SampleName1</name>
    <file>SampleFileName1</file>
    <fav>true</fav>
  </CSound>
  <CSound>
    <id>2</id>
    <name>SampleName2</name>
    <file>SampleFileName2</file>
    <fav>false</fav>
  </CSound>
  <CSound>
    <id>3</id>
    <name>SampleName3</name>
    <file>SampleFileName3</file>
    <fav>true</fav>
  </CSound>
  <CSound>
    <id>4</id>
    <name>SampleName4</name>
    <file>SampleFileName4</file>
    <fav>false</fav>
  </CSound>
  <CSound>
    <id>5</id>
    <name>SampleName5</name>
    <file>SampleFileName5</file>
    <fav>true</fav>
  </CSound>
</ArrayOfSounds>

我正在尝试使用这部分代码进行反序列化

   Assembly assembly = typeof(App).GetTypeInfo().Assembly;
   Stream stream = assembly.GetManifestResourceStream("SaynarSounds.Resources.XML.Sounds.xml");

   List<CSound> sounds;
   using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
   
       XmlSerializer serializer = new XmlSerializer(typeof(List<CSound>));
       sounds = (List<CSound>)serializer.Deserialize(reader);
   

   if (sounds == null)
   
       sounds = new List<CSound>();
   

   return sounds;

找到资源并开始加载,但在反序列化时出现此错误:

System.InvalidOperationException: XML 文档中存在错误。

你能帮帮我吗?

更新:

异常抛出此消息

[错误] 致命的未处理异常:System.InvalidOperationException: XML 文档中存在错误。 ---> System.InvalidOperationException:不是 预计 02-04 12:29:58.045 E/mono-rt (3046): at System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadRoot (System.Xml.Serialization.XmlTypeMapping rootMap) [0x0005b] 在 /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs:182 02-04 12:29:58.045 E/mono-rt (3046): at System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadRoot () [0x00028] 在 /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs:87 02-04 12:29:58.045 E/mono-rt (3046): at System.Xml.Serialization.XmlSerializer.Deserialize (System.Xml.Serialization.XmlSerializationReader 阅读器)[0x0001c] 在 /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/System.XML/System.Xml.Serialization/XmlSerializer.cs:364

但我没有xmlns=''

【问题讨论】:

【参考方案1】:

您的问题是,如果您尝试序列化 List&lt;CSounds&gt; 类型的根对象,您将获得如下 XML:

<ArrayOfCSound>
  <CSound>
    <id>one</id>
  </CSound>
</ArrayOfCSound>

注意到根元素&lt;ArrayOfX&gt; 以与嵌套项元素&lt;X&gt; 相同的字符串X 结尾?这与根元素名为ArrayOfSound 但项目元素名为CSound 的示例XML 不一致。

要解决这种不一致问题,您需要引入一个根类型,如下所示:

[XmlRoot("ArrayOfSounds")]
public class CSoundsRoot

    public CSoundsRoot()  this.Sounds = new List<CSound>(); 

    [XmlElement("CSound")]
    public List<CSound> Sounds  get; set; 

然后做:

XmlSerializer serializer = new XmlSerializer(typeof(CSoundsRoot))
var root = (CSoundsRoot)serializer.Deserialize(reader);
var sounds = root == null ? new List<CSounds>() : root.Sounds;

顺便说一句,XML 反序列化中的错误通常可以通过序列化您的类型并将观察到的 XML 与预期的 XML 进行比较来诊断。

示例fiddle。

【讨论】:

以上是关于在 Xamarin 中反序列化 XML的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中反序列化具有属性的 XML [重复]

如何在 C# 中反序列化具有前缀的 XML

C# Restful WCF 服务。无法在帖子正文中反序列化 XML

在 C# 中反序列化 XML 元素的存在以布尔

从使用 XSD.exe 生成的 XML 中反序列化类

将对象序列化为 XElement 并在内存中反序列化