繁体   English   中英

选择两个系统属性之一

[英]Choose one of two system attributes

我需要创建读取/写入xml配置的配置器。 config的部分格式如下:

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

使用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接口,它提供了更大的灵活性,但是更加复杂

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM