使用XmlSerializer反序列化XML的替代方法

Sim*_*ood 4 c# xmlserializer uwp

我正在编写UWP应用程序,并希望将xml中的列表反序列化为Objects列表:

<List>
    <Element Name="A">
        <SubElement Name="A1"> 
            <Color> Blue </Color> 
            <Color> Red </Color> 
        </SubElement>
        <SubElement Name="A2"> 
            <Color> Blue </Color> 
            <Color> Green </Color>  
        </SubElement>
    </Element>
    <Element Name="B">
        <SubElement Name="B1"> 
            <Color> Yellow </Color> 
            <Color> Red </Color> 
        </SubElement>
        <SubElement Name="B2"> 
            <Color> Yellow </Color> 
            <Color> Green </Color>  
        </SubElement>
    </Element>
    <Element Name="C"/>
        <SubElement Name="C1"> 
            <Color> Purple </Color> 
            <Color> Red </Color> 
        </SubElement>
        <SubElement Name="C2"> 
            <Color> Purple </Color> 
            <Color> Green </Color>  
        </SubElement>
    </Element>
</List> 
Run Code Online (Sandbox Code Playgroud)

这些类如下所示:

public class Element
{
    [XmlAttribute]
    public string Name { get; set; }

    [XmlElement("SubElement")]
    public List<SubElement> _subelement { get; set; }
}

public class SubElement
{
      [XmlElement("Color")]
      public string Color{ get; set; }

      [XmlAttribute("Name")]
      public string Name { get; set; } 
}
Run Code Online (Sandbox Code Playgroud)

我的C#代码如下所示:

XDocument doc = XDocument.Load("list.xml");
XElement node = doc.Descendants(XName.Get("List")).FirstOrDefault();
var serializer = new XmlSerializer(typeof(List<Element>), new XmlRootAttribute("List"));
var elementList = serializer.Deserialize(node.CreateReader()) as List<Element>;
Run Code Online (Sandbox Code Playgroud)

在调试模式下,此应用程序可以正常运行。在发布模式下PlatformNotSupportedException,出现线程错误。我发现问题一定与Compile with .NET Native tool chain项目设置中的“ 选项”有关。但是我没有找到解决问题的办法。

我的问题:对于上面显示的代码,有没有一种简单的替代方法可以将XML反序列化为对象,而不使用XmlSerializer且可以在UWP应用中使用?

dbc*_*dbc 5

在您重写的问题中,您的XML似乎具有元素和属性混合的任意复杂性。您正在寻找一种无需使用即可自动反序列化此XML的方法XmlSerializer,这基本上相当于编写另一个XML序列化程序

由于这是不平凡的(不在stackoverflow答案的范围内),一种快速的解决方法是将XML转换为其他序列化程序可以识别的格式,并使用该格式。可能性包括:

  1. DataContractSerializer。该序列化程序用于XML反序列化,但不支持:

    • XML属性反序列化
    • 将序列(例如<Element /><Element/>)反序列化为没有外部元素的集合。

    因此,尽管可以使用此序列化器将XML反序列化为某些合适的数据模型,但仍需要使用LINQ to XML进行大量预处理。

  2. Json.NET。如在JSON和XML之间转换中所述,此序列化程序支持XML到JSON的转换,因此可能适合您的需求。

如果选择选项2,则可以按以下方式定义数据模型:

public class RootObject
{
    [JsonConverter(typeof(SingleOrArrayConverter<Element>))]
    public List<Element> Element { get; set; }
}

public class Element
{
    [XmlAttribute]
    [JsonProperty("@Name")]
    public string Name { get; set; }

    [XmlElement("SubElement")]
    [JsonProperty("SubElement")]
    [JsonConverter(typeof(SingleOrArrayConverter<SubElement>))]
    public List<SubElement> _subelement { get; set; }
}

public class SubElement
{
    [XmlElement("Color")]
    [JsonConverter(typeof(SingleOrArrayConverter<string>))]
    public List<string> Color { get; set; }

    [XmlAttribute("Name")]
    [JsonProperty("@Name")]
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并反序列化如下:

var doc = XDocument.Parse(xmlString);

// Convert the XDocument to an intermediate JToken hierarchy.
var converter = new Newtonsoft.Json.Converters.XmlNodeConverter { OmitRootObject = true };
var rootToken = JObject.FromObject(doc, JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = { converter } }));

// Convert the JTOken to a RootObject
var rootObj = rootToken.ToObject<RootObject>();
Run Code Online (Sandbox Code Playgroud)

笔记:

工作。净提琴