繁体   English   中英

如何强制XmlSerializer将元素序列化为已编译类型的属性?

[英]How to force a XmlSerializer to serialize elements as attributes of a compiled type?

我提供了一些类似于以下内容的预定义XML:

<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Points>
      <Point X="1.345" Y="7.45" />
      <Point X="1.123" Y="5.564" />
      <Point X="3.34" Y="2.5345" />
   </Points>
   <!-- and a bunch of other attributes and structures which are perfectly serialized and deserialized by the XmlSerializer -->
</Root>

我的目标是使用XmlSerializer实例将其反序列化为List<System.Windows.Point> ,反之亦然。 因此,我定义了如下类型:

[Serializable]
[XmlRoot("Root")]
public class RootClass
{
   public List<System.Windows.Point> Points { get; set; }
   /* and more properties */
}

我的问题是XmlSerializer将框架属性解释为XmlElement 为了使它们仅按原样读写,而不按要求进行属性读写。

我考虑过的一种解决方案是定义一个自定义点类型,该点类型为每个坐标属性定义XmlAttribtueAttribute 并且此自定义点将映射到System.Windows.Point结构。 如下所示:

[XmlIgnore]
public List<Point> Points { get; set; }

[XmlArray("Points")]
[XmlArrayItem("Point")]
public List<CustomSerializedPoint> CustomSerializedPoints
{
    get { return this.Points.ToCustomSerializedPointList(); }
    set { this.Points = value.ToPointList(); }
}

但是对于这种解决方案,我注意到,从未调用过setter,而XmlSerializer大约调用了CustomSerializedPoints的getter了五次。 它期望有一个后备列表,每个调用具有相同的引用,并且永远不会为空。 为了满足这些要求,这对我来说不是解决方案,因为我需要将List<CustomSerializedPoints>保留在内存中,仅用于使用属性而不是元素来编写点。

那么有人有更可行的解决方案吗?

另外,我的XmlSerializer代码:

/* ... */
var serializer = new XmlSerializer(typeof(RootClass));
TextReader textReader = new StreamReader("file.xml");
(RootClass)serializer.Deserialize(textReader);
/* ... */

您可以通过在运行时更改类的序列化属性来更改类的序列化/反序列化方式。 XmlAttributeOverrides类提供了这种可能性。 以下示例代码正确地反序列化了您提供的XML:

XmlAttributes xa = new XmlAttributes();
XmlAttributes ya = new XmlAttributes();

xa.XmlAttribute = new XmlAttributeAttribute("X");
ya.XmlAttribute = new XmlAttributeAttribute("Y");

XmlAttributeOverrides xao = new XmlAttributeOverrides();
xao.Add(typeof(System.Windows.Point), "X", xa);
xao.Add(typeof(System.Windows.Point), "Y", ya);

var serializer = new XmlSerializer(typeof(RootClass), xao);
TextReader textReader = new StreamReader("file.xml");

var result = (RootClass)serializer.Deserialize(textReader);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM