C # XmlSerializer: сохранить значение, переопределить метку элемента - PullRequest
1 голос
/ 16 декабря 2011

В настоящее время я использую запрос LINQ для чтения XML-файла, например,

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

в список пользовательских объектов, содержащих пользовательские свойства HistoryString.HistoryString содержит 2 строки: 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) Отметьте previousValueсвойство с [System.Xml.Serialization.XmlIgnore], затем просмотрите строку XML, которая должна быть записана, удалив все следы <currentValue> и </currentValue>

2) Откройте существующий файл и вручную внесите любые обновления / удаления / добавления - этобезусловно, более длинная.

3) Есть ли способ HistoryString автоматически разрешать его currentValue вместо сериализации каждого из его свойств, подобно тому, как ToString () работает?

Я провел некоторые исследования в этой области, включая полезные статьи MSDN здесь и здесь , но я не вижу никаких других атрибутов, которые могли бы решить эту проблему, я все ещеЯ не уверен, возможно ли это.Есть идеи?

Ответы [ 2 ]

1 голос
/ 16 декабря 2011

Вот еще одна идея.Если вы определяете свой класс следующим образом:

[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.

0 голосов
/ 16 декабря 2011

Ну почему бы не сериализовать обратно, используя оригинальную схему, и передать в нее список преобразованных объектов из истории, используя только текущее значение?

например,

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