我有这个类的定义
public class Foo
{
}
反序列化到这个 xml 中
<?xml version="1.0"?>
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
</Foo>
此 xml 文件布局已存在于客户端计算机上。
我想将班级从
Foo
重命名为 Footastic
。
public class Footastic
{
}
现在称为类
Footastic
的任何新序列化,都应序列化为
<?xml version="1.0"?>
<Footastic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
</Footastic>
我的问题是如何告诉反序列化接受
Foo
或Footastic
?
我知道我可以通过指定
Footastic
属性将 Foo
“重命名”为 XmlRoot
。
[XmlRoot("Foo")]
public class Footastic
{
}
但这也会改变对象的任何新序列化,这是不希望的。
新的序列化应序列化为
Footastic
反序列化时仅支持包含旧名称 Foo
的旧 xml 文件。以防万一您需要反序列化/序列化的代码。我真的没有做任何花哨的事情。
反序列化:
Footastic
序列化:
public static T? Deserialize<T>(string fileName)
{
if (!File.Exists(fileName))
return default;
using FileStream streamReader = new(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using var xr = XmlReader.Create(streamReader);
XmlSerializer xmlDeSerializer = new(typeof(T));
return (T?)xmlDeSerializer.Deserialize(xr);
}
public static void Serialize<T>(T? value, string fileName)
{
if (value is null)
return;
Directory.CreateDirectory(Path.GetDirectoryName(fileName) ?? "");
using FileStream fileStream = new(fileName, FileMode.Create, FileAccess.Write, FileShare.Write);
using var streamWriter = XmlWriter.Create(fileStream, new()
{
Encoding = Encoding.UTF8,
Indent = true
});
XmlSerializer xmlSerializer = new(typeof(T));
xmlSerializer.Serialize(streamWriter, value);
}
替换为
Foo
。Footastic
像这样使用它。
public class FooReader : XmlTextReader
{
// Add other constructor overloads as needed.
public FooReader(string url) : base(url) { }
public override string LocalName
{
get
{
if (base.LocalName == "Foo")
return "Footastic";
return base.LocalName;
}
}
}
这将接受
var ser = new XmlSerializer(typeof(Footastic));
using var fooReader = new FooReader("test.xml");
var foo = (Footastic)ser.Deserialize(fooReader);
和
Foo
。不过,要小心!这将替换所有 Foo 元素!
如果其他地方的 xml 中存在同名元素,那么您需要进行额外的检查。