首页 > 解决方案 > XML 反序列化代码在控制台应用程序中有效,但在 Xamarin.Forms 中引发 NullReferenceException

问题描述

我有将 XMLDocument 反序列化为数组的代码。但只要我在 Xamarin.Forms Android 项目中调用它,它就会抛出 NullReferenceException。经过几天的调试,我创建了一个 .NET 控制台应用程序,将有问题的代码复制到其中,然后发现它完美无缺地工作。谁能帮我解决这个问题?这是我正在使用的 XMLDocument:

<?xml version="1.0" encoding="utf-8" ?>
<Otazky>
  <Otazka>
    <Typ>ABC</Typ>
    <Bodu>1</Bodu>
    <Ukol> Ve kterém z následujících souvětí není chyba v interpunkci?</Ukol>
    <Moznosti>
      <Moznost>A) Po vyčerpávajících mrazech</Moznost>
      <Moznost>B) Mé obavy se každým dnem stupňovaly,</Moznost>
      <Moznost>C) Pokud snížím množství sladkostí</Moznost>
      <Moznost>D) Rodiče celý víkend usilovně přemýšleli</Moznost>
    </Moznosti>
    <Spravna>C</Spravna>
  </Otazka>

<Otazka>
  <Typ>Vyber</Typ>
  <Bodu>2</Bodu>
  <Ukol> Ukol2 </Ukol>
  <Moznosti>
    <Moznost>A) Po vyčerpávajících mrazech</Moznost>
    <Moznost>B) Mé obavy se každým dnem stupňovaly</Moznost>
    <Moznost>C) Pokud snížím množství sladkostí</Moznost>
    <Moznost>D) Rodiče celý víkend usilovně přemýšleli</Moznost> 
  </Moznosti> 
  <Spravna>D</Spravna>
</Otazka>
</Otazky>

以下是我用来存储每个 Otazka 元素的类:

public class Otazka
{
    [XmlElement(ElementName = "Typ")]
    public string Typ { get; set; }
    [XmlElement(ElementName = "Bodu")]
    public int Bodu { get; set; }
    [XmlElement(ElementName = "Ukol")]
    public string Ukol { get; set; }

    [XmlElement(ElementName = "Moznosti")]
    public Moznosti Moznosti { get; set; }
    [XmlElement(ElementName = "Spravna")]
    public string Spravna { get; set; }
}

[XmlRoot(ElementName = "Otazky")]
public class Otazky
{
    [XmlElement(ElementName = "Otazka")]
    public List<Otazka> Otazka { get; set; }
}

最后是将 XML 反序列化到我的类中的代码:

Otazka[] LoadXMLData()
{
                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DDKTCKE_APP.MyResources.Otazky.xml"))
                {
                    XDocument doc = XDocument.Load(stream);

                    var result = from q in doc.Descendants("Otazka")
                             select new Otazka
                             {
                                 Typ = q.Element("Typ").Value,
                                 Bodu = Convert.ToInt32(q.Element("Bodu").Value),
                                 Ukol = q.Element("Ukol").Value,
                                 Moznosti = new Moznosti(q.Element("Moznosti").Elements().Select(x => x.Value).ToList()),                                                            
                                 Spravna = q.Element("Spravna").Value
                             };

                    return result.ToArray();

                }
}

NullReferenceException 在返回 results.ToArray() 的行中抛出。此外,当我将整个函数包含在 Try...Catch 块中时,它没有捕获任何东西。

标签: c#xmlxamarin.formsdeserializationnullreferenceexception

解决方案


xml 包含 unicode 字符,而 ident(第一行)表示 utf-8。因此,您需要跳过 ident 行,以免发生冲突。请参阅下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            Otazka[] otazka = LoadXMLData(FILENAME);
        }
        static Otazka[] LoadXMLData(string filename)
        {
            using (var stream = File.OpenRead(filename))
            {
                StreamReader reader = new StreamReader(stream);
                reader.ReadLine();  //read line to skip xml identification line which is utf-8
                                    //file contains unicode characters
                XDocument doc = XDocument.Load(reader);

                //_Counter = doc.ToString().Length;


                var result = (from q in doc.Descendants("Otazka")
                             select new Otazka
                             {
                                 Typ = q.Element("Typ").Value,
                                 Bodu = Convert.ToInt32(q.Element("Bodu").Value),
                                 Ukol = q.Element("Ukol").Value,
                                 //Moznosti = new Moznosti(q.Element("Moznosti").Elements().Select(x => x.Value).ToList()),
                                 Spravna = q.Element("Spravna").Value
                             }).ToArray();

                return result;

            }
        }
    }

    public class Otazka
    {
        [XmlElement(ElementName = "Typ")]
        public string Typ { get; set; }
        [XmlElement(ElementName = "Bodu")]
        public int Bodu { get; set; }
        [XmlElement(ElementName = "Ukol")]
        public string Ukol { get; set; }

        //[XmlElement(ElementName = "Moznosti")]
        //public Moznosti Moznosti { get; set; }
        [XmlElement(ElementName = "Spravna")]
        public string Spravna { get; set; }
    }

    [XmlRoot(ElementName = "Otazky")]
    public class Otazky
    {
        [XmlElement(ElementName = "Otazka")]
        public List<Otazka> Otazka { get; set; }
    }
}

推荐阅读