使用.NET XML序列化在其他元素中包装序列化属性

我使用C#+ VSTS2008 + .Net 3.0来进行XML序列化。 代码工作正常。 下面是我的代码和当前序列化的XML结果。

现在我想在输出XML文件中添加两个附加层。 这是我期望的XML结果。 有什么简单的方法吗? 我不确定NestingLevel是否可以帮助这样做。 我想找到一种不会改变MyClass和MyObject结构的简单方法。

预期的XML序列化结果,

     Foo     

当前的XML序列化结果,

    Foo   

我目前的代码,

 public class MyClass { public MyObject MyObjectProperty; } public class MyObject { public string ObjectName; } public class Program { static void Main(string[] args) { XmlSerializer s = new XmlSerializer(typeof(MyClass)); FileStream fs = new FileStream("foo.xml", FileMode.Create); MyClass instance = new MyClass(); instance.MyObjectProperty = new MyObject(); instance.MyObjectProperty.ObjectName = "Foo"; s.Serialize(fs, instance); return; } } 

我想找到一种不会改变MyClass和MyObject结构的简单方法。

坦率地说,这不会发生。 XmlSerializer (简单地使用时)遵循类/成员的结构。 因此,您无法在不更改结构的情况下添加额外的图层。

当以定制的方式使用( IXmlSerializable )时,您可以肯定的一点是它并不简单……这不是一个有趣的界面来实现。

我的建议:介绍一个模仿你想要的格式的DTO,并在序列化之前填充它。

为什么还需要这两个额外的图层?

是业务需求,您应该将这两个对象添加到对象模型中:

 public class MyClass { public AdditionalLayer1 AdditionalLayer1; } public class AdditionalLayer1 { public AdditionalLayer2 AdditionalLayer2; } public class AdditionalLayer2 { public MyObject MyObjectProperty; } public class MyObject { public string ObjectName; } 

如果纯粹是因为某些兼容性要求,你可以做上面的事情,或者在MyClass上实现IXmlSerializable:

 public class MyClass : IXmlSerializable { public MyObject MyObjectProperty; public void WriteXml (XmlWriter writer) { //open the two layers //serialize MyObject //close the two layers } public void ReadXml (XmlReader reader) { //read all the layers back, etc } public XmlSchema GetSchema() { return(null); } } 

您可以在序列化后使用XSL进行转换并添加“缺失”标记。

我建议序列化到MemoryStream而不是FileStream ,然后将XML加载到XmlDocument ,然后使用该类的方法插入所需的额外节点。 之后,您可以将其保存。

我最近才这样做,并没有发现在所有困难或复杂的情况下重写IXmlSerializable接口。 序列化/反序列化正常但对于包含子类的类,您需要在IXmlSerializable派生的额外标记中包含该子类:

 class ContainingClass : IXmlSerializable { ... #region IXmlSerializable Members public XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { **reader.ReadStartElement("Equipment");** XmlSerializer ser = new XmlSerializer(typeof(Host)); while (reader.NodeType != XmlNodeType.EndElement) { Host newHost = new Host(); newHost.Name = (string) ser.Deserialize(reader); _hosts.Add(newHost); reader.Read(); } // Read the node to its end. // Next call of the reader methods will crash if not called. **reader.ReadEndElement(); // "Equipment"** } public void WriteXml(XmlWriter writer) { XmlSerializer ser = new XmlSerializer(typeof(Host)); **writer.WriteStartElement("Equipment");** foreach (Host host in this._hosts) { ser.Serialize(writer, host); } **writer.WriteEndElement();** } #endregion 

我在这里所做的就是包装低级对象的de / serialization。 在这里,我在这个类的集合中的所有主机周围包装了一个额外的标签“Equipment”。 您可以在此处添加任意数量的标签,只要您关闭每个标签即可。

注意:Bold显示为**文本** – 只是确保你摆脱双星号:)