gpt4 book ai didi

c# - 在基类中实现 IXmlSerializable 时如何恢复到 'default' XML 序列化?

转载 作者:太空狗 更新时间:2023-10-29 20:32:32 25 4
gpt4 key购买 nike

我正在尝试序列化一个继承自实现 IXmlSerializable 的基类的类。

名为 PropertyBag 的基类是一个允许动态属性的类 (credits to Marc Gravell)。

我实现了 IXmlSerializable,以便将动态属性(存储在字典中)编写为普通的 xml 元素。

例如在序列化具有公共(public)属性(非动态)Name 和动态属性 Age 的类 Person 时,我希望它生成以下 XML:

<Person>
<Name>Tim</Name>
<DynamicProperties>
<Country>
<string>USA</string>
</Country>
</DynamicProperties>
<Person>

我可以获得该部件以在基类 PropertyBag 中使用以下 WriteXml 实现:

public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement("DynamicProperties");

// serialize every dynamic property and add it to the parent writer
foreach (KeyValuePair<string, object> kvp in properties)
{
writer.WriteStartElement(kvp.Key);

StringBuilder itemXml = new StringBuilder();
using (XmlWriter itemWriter = XmlWriter.Create(itemXml))
{
// serialize the item
XmlSerializer xmlSer = new XmlSerializer(kvp.Value.GetType());
xmlSer.Serialize(itemWriter, kvp.Value);

// read in the serialized xml
XmlDocument doc = new XmlDocument();
doc.LoadXml(itemXml.ToString());

// write to modified content to the parent writer
writer.WriteRaw(doc.DocumentElement.OuterXml);
}

writer.WriteEndElement();
}

writer.WriteEndElement();
}

但是,在序列化 Person 类时,它不再序列化普通(非动态)属性,除非我覆盖 Person 中的 WriteXml 方法(我不想这样做)。有什么办法可以在基类中自动添加静态属性吗?我知道我可以使用反射手动执行此操作,但我想知道 .Net Framework 中是否有一些内置功能?

最佳答案

我在 XmlSerializer(以及其他各种序列化 API)上花费了很多时间,我很确定这很简单:你做不到。实现 IXmlSerializable 要么全有,要么全无。

我能想到的最接近的是作弊并将所有固定属性移动到一个子对象;这会给你稍微不同的 xml - 类似于:

<FixedProperties>
<Name>Tim</Name>
</FixedProperties>
<DynamicProperties>
<Country>
<string>USA</string>
</Country>
</DynamicProperties>

但我希望它会起作用。您将在基础对象上具有直通属性:

[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public FixedProperties FixedProps {get;set;}
public string Name {
get {return FixedProps.Name;}
set {FixedProps.Name = value;}
}

有道理吗?您也可以将 Name 标记为 [XmlIgnore],但这看起来很多余。在您定制的序列化方法中,您将使用 new XmlSerializer(typeof(FixedProperties))

编辑:这是一个有效的“序列化”示例:

using System;
using System.ComponentModel;
using System.Xml.Serialization;

static class Program
{
static void Main()
{
MyType obj = new MyType { Name = "Fred" };
var ser = new XmlSerializer(obj.GetType());
ser.Serialize(Console.Out, obj);
}
}
public class MyType : IXmlSerializable
{
public MyType()
{
FixedProperties = new MyTypeFixedProperties();
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public MyTypeFixedProperties FixedProperties { get; set; }
[XmlIgnore]
public string Name
{
get { return FixedProperties.Name; }
set { FixedProperties.Name = value; }
}

System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
{
return null;
}

void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
{
throw new System.NotImplementedException();
}

void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement("DynamicProperties");
writer.WriteElementString("Foo", "Bar");
writer.WriteEndElement();
fixedPropsSerializer.Serialize(writer, FixedProperties);
}
static readonly XmlSerializer fixedPropsSerializer
= new XmlSerializer(typeof(MyTypeFixedProperties));

}
[XmlRoot("FixedProperties")]
public class MyTypeFixedProperties
{
public string Name { get; set; }
}

关于c# - 在基类中实现 IXmlSerializable 时如何恢复到 'default' XML 序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1982916/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com