2017-10-04 83 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,让更多的灵活性,但它是一个有点复杂