选择两个系统属性之一

时间:2017-10-04 07:40:58

标签: c# .net xml

我需要创建读/写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);
        }
    }
}

1 个答案:

答案 0 :(得分: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,它提供了更大的灵活性,但它更复杂一些