【问题标题】:XmlSerializer Serialize with a default XmlRootXmlSerializer 使用默认 XmlRoot 进行序列化
【发布时间】:2011-12-14 19:46:05
【问题描述】:

当我序列化一个对象时,是否在 XmlSerializer 中添加一个 XML 根元素或“包装器”?

我正在寻找的 XML 是这样的:

<Groups>
    <Group method="ModifySubGroups" ID="1234" PIN="5678">
        <SubGroup action="Delete" number="95">
            <Name>Test</Name>
        </SubGroup>
    </Group>
</Groups>

我有两个类,Group 和 SubGroup。组包含子组的通用列表。它工作得很好,但我没有 XML 根“组”。使用 Group 和 SubGroup 这两个类会产生这样的结果:

<Group method="ModifySubGroups" ID="1234" PIN="5678">
   <SubGroup action="Delete" number="95">
       <Name>Test</Name>
   </SubGroup>
</Group>

我可以让它工作的唯一方法是创建另一个包含 Group 的类“Groups”。所以现在我有三个类,Groups、Group 和 SubGroup。 Groups 包含 Group,Group 包含 SubGroup。

还有其他想法吗?

【问题讨论】:

    标签: c# .net xml xml-serialization


    【解决方案1】:

    您通常不会使用 XML 序列化来使 XML 更漂亮。如果你需要一个根容器元素,那么你需要有一个根容器对象,并序列化它而不是 Group 对象。

    但是,您可以序列化 Group 对象的数组

    void Main()
    {
        var g = new Group();
        g.SubGroups.Add(new SubGroup {Name = "aaa"});
    
        var ser = new XmlSerializer(typeof(Group[]), new XmlRootAttribute("Groups"));
        using (var w = new StringWriter())
        {
            ser.Serialize(w, new Group[] {g});
            w.ToString().Dump();
        }
    }
    
    public class Group
    {
        [XmlElement("SubGroup")]
        public List<SubGroup> SubGroups = new List<SubGroup>();
    }
    
    public class SubGroup
    {
        public string Name;
    }
    

    这自然意味着反序列化代码需要神奇地知道总是有一个且只有一个 Group 元素,或者假设可能有 0 个或更多。老实说,除非您真的想序列化组的集合,否则我认为这样做没有多大意义。这只会增加混乱。

    【讨论】:

    • 我对此没有任何控制权。提供 Web 服务的供应商需要这种方式。这很好用。谢谢!
    • @vincentw56 如果您必须遵守现有架构,请查看我编辑的答案
    • 注意:可能存在内存泄漏! msdn.microsoft.com/ru-ru/magazine/cc163491.aspx
    【解决方案2】:

    编辑:如果您真的想遵守供应商架构,那么您是从错误的角度开始的。 您根本不需要实现这样的类,您只需使用供应商 XSD 并使用 Visual Studio 提供的 xsd utility 从您的架构生成 .net 类,您还可以选择您想要序列化对象的方式 -使用XmlSerializerDataContractSerializer(我想说这会给你更好的灵活性)

    注意:如果您没有工具并且不知道如何自己编写,您可以使用一些工具从您的 xml 生成 xsd

    您可以使用XmlRootAttribute 来指定自定义 XML 根

    此外,当您序列化集合时,您可以指定包装器 - 请参阅 Array Serializing

    【讨论】:

    • 当我在 XmlSerializer 的构造函数中这样做时,它只是将“Group”替换为“Groups”。它不添加根元素或“包装器”。
    • XmlArrayXmlArrayItem 不适用于根元素。
    • 数据协定在这种情况下不起作用,因为它们不支持 XML 属性。
    • 谢谢 vittore,我会试试看效果如何。
    • 我查看了 XSD 实用程序,它生成良好。虽然不是我需要的。我使用自己的类的原因是因为它们用于其他事情,而不仅仅是供应商的 Web 服务。我没有看到需要编写两个不同的类对象并将它们映射在一起。上面接受的解决方案非常适合我的情况。谢谢。
    猜你喜欢
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    相关资源
    最近更新 更多