c# XmlSerializer:保留值,覆盖元素标签
本文关键字:覆盖 元素 标签 XmlSerializer 保留 | 更新日期: 2023-09-27 18:18:08
我目前正在使用LINQ查询读取XML文件,例如
<MyObjects>
<MyObject>
<MyElement>some_text</MyElement>
<MyOtherElement>some_more_text</MyOtherElement>
</MyObject>
</MyObjects>
转换为包含自定义HistoryString
属性的自定义对象列表。HistoryString
包含两个字符串,一个currentValue
和一个previousValue
。
这一切都很好,除了当使用XmlSerializer将自定义对象写回XML文件时,输出相当明显地包含额外的标记,即
<MyObjects>
<MyObject>
<MyElement>
<currentValue>some_text</currentValue>
<previousValue>some_text</previousValue>
</MyElement>
<MyOtherElement>
<currentValue>some_more_text</currentValue>
<previousValue>some_more_text</previousValue>
</MyOtherElement>
</MyObject>
</MyObjects>
问:基于这种基本差异,以相同格式读写XML的最简洁和/或最有效的方法是什么?
一些初步的想法:
1)用[System.Xml.Serialization.XmlIgnore]
标记previousValue
属性,然后扫描要写的XML字符串,删除<currentValue>
和</currentValue>
的所有痕迹
2)打开现有的文件,手动进行任何更新/删除/添加-这肯定更冗长。
3)有一个HistoryString
自动解析到它的currentValue
,而不是序列化它的每个属性的任何方法,类似于ToString()的工作方式?
我对此做了一些研究,包括有用的MSDN文章在这里和在这里,但我看不到任何其他属性可以解决这个问题,我仍然不确定这是否可能。什么好主意吗?
这是另一个想法。如果你这样定义你的类:
[Serializable]
public class MyObject
{
[XmlElement(ElementName = "MyElement")]
public string CurrentValueElement
{
get
{
return Element.CurrentValue;
}
set
{
Element = new MyElement
{
CurrentValue = value, PreviousValue = value
};
}
}
[XmlElement(ElementName = "MyOtherElement")]
public string CurrentValueOtherElement
{
get
{
return OtherElement.CurrentValue;
}
set {}
}
[XmlIgnore]
public MyElement Element { get; set; }
[XmlIgnore]
public MyElement OtherElement { get; set; }
}
然后,当对象被序列化时,输出的XML将与您的示例完全相同。
同样,如果你像这样扩展CurrentValueElement/CurrentValueOtherElement setter:
[XmlElement(ElementName = "MyElement")]
public string CurrentValueElement
{
get
{
return Element.CurrentValue;
}
set
{
Element = new MyElement
{
CurrentValue = value, PreviousValue = value
};
}
}
然后,您将能够使用XmlSerializer直接反序列化您的对象,而无需诉诸LINQ。
那么,为什么不使用原始模式进行序列化,并将仅使用当前值的历史转换对象列表馈送给它呢?
。
from h in HistoryEntryList
select new OriginalEntry{ field = h.field.current_value, ... };