C#XmlSerializer:保留值,覆盖元素标签

时间:2011-12-16 12:22:24

标签: c# xml xml-serialization

我目前正在使用LINQ查询来读取XML文件,例如

<MyObjects>
   <MyObject>
       <MyElement>some_text</MyElement>
       <MyOtherElement>some_more_text</MyOtherElement>
   </MyObject>
</MyObjects>

到包含自定义HistoryString属性的自定义对象列表中。 HistoryString包含2个字符串,currentValuepreviousValue

这一切都很有效,除非使用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)用previousValue标记[System.Xml.Serialization.XmlIgnore]属性,然后浏览要写入的XML字符串,删除<currentValue></currentValue>

的所有痕迹

2)打开现有文件并手动进行任何更新/删除/添加 - 这肯定会更长时间。

3)任何方式让HistoryString自动解析为currentValue而不是序列化其每个属性,类似于ToString()的工作方式?

我已对此进行了一些研究,包括有用的MSDN文章herehere,但我看不到任何可以解决此问题的其他属性,我仍然不确定这是否可行。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

这是另一个想法。如果你这样定义你的类:

[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设置器:

[XmlElement(ElementName = "MyElement")]
public string CurrentValueElement
{
    get
    {
        return Element.CurrentValue;
    }

    set
    {
        Element = new MyElement
                      {
                          CurrentValue = value, PreviousValue = value
                      };
    }
}

然后,您将能够使用XmlSerializer直接反序列化对象,而无需使用LINQ。

答案 1 :(得分:0)

那么为什么不使用原始模式进行序列化,并仅使用当前值从历史中输入转换对象的列表?

e.g。

from h in HistoryEntryList
select new OriginalEntry{ field = h.field.current_value, ... };