2

次のような事前定義された 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>

私の目標は、それをインスタンスをList<System.Windows.Point>使用して逆シリアル化することです。XmlSerializerしたがって、次のような型を定義しました。

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

私の問題は、XmlSerializerがフレームワーク プロパティを として解釈することXmlElementです。そのために、それらは必要な属性としてではなく、そのようにのみ読み書きされます。

私が考えた 1 つの解決策は、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(); }
}

XmlSerializerしかし、このソリューションでは、セッターが呼び出されることはなく、ゲッターがCustomSerializedPoints約5回呼び出されることに気付きました。各呼び出しで同じ参照を持ち、null になることのないバッキング リストがあることが期待されます。その要件を満たすために、これは私にとって解決策ではありませんList<CustomSerializedPoints>。要素の代わりに属性を使用してポイントを書き込むためだけにメモリ内に保持する必要があるからです。

それで、誰かがより実用的な解決策を持っていますか?

さらに私のXmlSerializerコード:

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

1 に答える 1

4

実行時にシリアライゼーション属性を変更することで、クラスがシリアライズ/デシリアライズされる方法を変更できます。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);
于 2013-10-18T00:04:45.713 に答える