2013-10-17 43 views
2

我給類似這樣一些預定義的XML:如何強制XmlSerializer將元素序列化爲編譯類型的屬性?

<?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(); } 
} 

但這種解決方案我已經注意到,該設置器永​​遠不會被調用,而XmlSerializer調用的CustomSerializedPoints約五倍,吸氣。它期望有一個支持列表,每個調用都有相同的引用,並且它不會爲空。爲了達到這個要求,這對我來說不是解決方案,因爲我需要將List<CustomSerializedPoints>保留在內存中,只是爲了使用屬性而不是元素來編寫點。

那麼,有人有一個更可行的解決方案?

另外我XmlSerializer代碼:

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

看到「[XmlSerializer類](http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer。 aspx)「,然後告訴我們你是否有更多的問題。 –

回答

4

你可以改變一個類被序列化的方式/通過改變其序列化反序列化屬性在運行時。 XmlAttributeOverrides類提供了這種可能性。下面的示例代碼正確deseralizes您所提供的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); 
+0

同時我也有類似的東西,但你比較快。謝謝,這解決了這個問題。 –

相關問題