2017-10-04 80 views
1

我需要創建配置程序,其中讀/寫XML配置。配置的 一部分是以下形式:選擇兩個系統屬性之一

<camera> 
    <id>1</id> 
    <name>Camera 1</name> 
    <address>http://192.168.1.100</address> 
    <roi> 
     <rect> 
      <x>100</x> 
      <y>200</y> 
      <width>300</width> 
      <height>150</height> 
     </rect> 
     <rect> 
      <x>350</x> 
      <y>400</y> 
      <width>200</width> 
      <height>250</height> 
     </rect> 
    </roi> 
</camera> 

但輸出我需要與XML格式屬性:

<camera id="1" name="Camera 1" address="http://192.168.1.100"> 
    <roi> 
     <rect x="100" y="200" width="300" height="150 /> 
     <rect x="350" y="400" width="200" height="250 /> 
    </roi> 
</camera> 

創建爲每個主節點的類,但我不知道如何選擇反序列化屬性是否應該是XmlElement,序列化應該是XmlAttribute。或者,我是否爲第一種形式的xml和第二種形式創建了兩個單獨的類?我是C#和.NET的初學者,所以還有其他方面的建議和意見嗎?

C#代碼:

[System.Serializable()] 
public class CamerasConfigAttrib 
{ 
    private int id; 
    private string name; 
    private string address; 
    private Collection<Rectangle> roi; 

    [XmlAttribute("id", Form = XmlSchemaForm.Unqualified)] 
    public int Id 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    [XmlAttribute("name", Form = XmlSchemaForm.Unqualified)] 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    [XmlAttribute("address", Form = XmlSchemaForm.Unqualified)] 
    public string Address 
    { 
     get { return address; } 
     set { address = value; } 
    } 

    [XmlArray("roi", Form = XmlSchemaForm.Unqualified)] 
    [XmlArrayItem("rect", typeof(Rectangle), Form = XmlSchemaForm.Unqualified] 
    public Collection<Rectangle> Roi 
    { 
     get { return roi; } 
     set 
     { 
      foreach (var rect in value) 
       roi.Add(rect); 
     } 
    } 
} 
+0

,我認爲你必須作出兩個不同的類,但如果有更好的方式來做到這一點,我感興趣 – GGO

+0

您應該創建一個XSLT並使用'XslCompiledTransform'來創建新的XML。 – Sefe

回答

0

使用XmlAttributeOverrides連載你反對另一個結構(你可以用它也能反序列化)。這裏是一個簡短的樣本如何在你的情況下使用它:

[Serializable] 
[XmlRoot("camera")] 
public class CamerasConfigAttrib : IXmlSerializable 
{ 
    [XmlElement("id")] 
    public int Id { get; set; } 

    [XmlElement("name")] 
    public string Name { get; set; } 
} 

過程代碼:

// sample data 
var xml = @"<camera><id>1</id><name>Camera 1</name></camera>"; 
// deserialization according to a native attributes 
var camera = (CamerasConfigAttrib)new XmlSerializer(typeof(CamerasConfigAttrib)) 
       .Deserialize(new StringReader(xml)); 
// prepare overridings 
var overrides = new XmlAttributeOverrides(); 
overrides.Add(typeof (CamerasConfigAttrib), "Id", 
    new XmlAttributes 
    { 
     XmlAttribute = new XmlAttributeAttribute("Id") 
    }); 
overrides.Add(typeof(CamerasConfigAttrib), "Name", 
    new XmlAttributes 
    { 
     XmlAttribute = new XmlAttributeAttribute("name") 
    }); 
// serializer initiated with overridings 
var s = new XmlSerializer(typeof(CamerasConfigAttrib), overrides); 
var sb = new StringBuilder(); 
s.Serialize(new StringWriter(sb), camera); 

結果

<?xml version="1.0" encoding="utf-16"?> 
<camera xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Id="1" name="Camera 1" /> 

在我看來,這種方式更自然,並沒有按不需要額外的類或文件。

作爲替代方案可以實現界面IXmlSerializable,讓更多的靈活性,但它是一個有點複雜