时间:2016-11-24 16:58:03

标签: c# xml oop types xmlserializer

像这样序列化和反序列化XML的最佳对象模型是什么:

<root>
    <header>
        <elementA>Example</elementA>
        <elementB>Test</elementB>
    </header>
    <content>
        <elementC>foo</elementC>
        <variousTypeA>
            <itemA>Test</itemA>
            <itemB>Test</itemB>
            <itemC>Test</itemC>
        </variousTypeA>
    </content>
</root>

我的问题是用其他类似的方式更新variousTypeA:

<root>
    <header>
        <elementA>Example</elementA>
        <elementB>Test</elementB>
    </header>
    <content>
        <elementC>foo</elementC>
        <variousTypeB>
            <itemZ>Test</itemZ>
            <itemY>Test</itemY>
            <itemX>Test</itemX>
        </variousTypeB>
    </content>
</root>

使用

生成XML的最佳选择是什么
XmlSerializer xmlSerializer = new XmlSerializer(typeof(variousTypeA));

XmlSerializer xmlSerializer = new XmlSerializer(typeof(variousTypeB));

但不重复共同的元素......

架构必须可以与C#XmlSerializer类一起使用。 你有建议的对象模型吗?

1 个答案:

答案 0 :(得分:0)

一种解决方案是创建一个对应于各种可能的<content>元素的类层次结构,如下所示:

public abstract class ContentBase
{
    public string elementC { get; set; }
}

public class ContentA : ContentBase
{
    public VariousTypeA variousTypeA { get; set; }
}

public class ContentB : ContentBase
{
    public VariousTypeB variousTypeB { get; set; }
}

然后,对于与<root>元素对应的POCO,创建一个类层次结构,其中基类型指定公共属性,派生类型是指示Content对象的特定类型的泛型,受约束属于ContentBase类型:

public abstract class RootBase
{
    public Header header { get; set; }

    [XmlIgnore]
    // The following provides get-only access to the specific content of this root
    public abstract ContentBase BasicContent { get; }
}

public class Header
{
    public string elementA { get; set; }
    public string elementB { get; set; }
}

[XmlRoot(ElementName = "root")]
public class Root<TContent> : RootBase 
    where TContent : ContentBase
{
    public TContent content { get; set; }

    public override ContentBase BasicContent { get { return content; } }
}

然后使用它:

var rootA = (Root<ContentA>)new XmlSerializer(typeof(Root<ContentA>)).Deserialize(new StringReader(xmlStringA));

var rootB = (Root<ContentB>)new XmlSerializer(typeof(Root<ContentB>)).Deserialize(new StringReader(xmlStringB));

此设计允许共享与<root><content>的常见元素相关的代码。

示例fiddle