Разделите поля объекта на два файла путем сериализации DataContract - PullRequest
2 голосов
/ 13 октября 2019

Я использую DataContractSerializer и хочу разделить данные одного и того же объекта на несколько файлов.

[DataContract]
public class TestObj
{
    [DataMember]
    protected double field1 = 0.0;

    [DataMember]
    protected double field2 = 0.0;
}

В частности, я хочу сохранить field1 в одном файле XML и field2 в другомXML-файлЕсть ли способ сделать это с помощью сериализации контракта данных?

Вот как я сейчас сериализуюсь:

DataContractSerializer serializaer = new DataContractSerializer(GetType(), null,
              0x7FFFFFFF /*maxItemsInObjectGraph*/,
              false /*ignoreExtensionDataObject*/,
              true /*preserveObjectReferences : this is most important to me */,
              null /*dataContractSurrogate*/);
var fs = File.Open(fName, FileMode.Create);
serializaer.WriteObject(fs, this);

fs.Dispose();
return true;

Ответы [ 2 ]

1 голос
/ 13 октября 2019

Я могу предложить использовать Custom Xml Writer в сочетании с сериализатором.

public class CustomWriter : XmlTextWriter
{
    public CustomWriter(TextWriter writer) : base(writer) { }
    public CustomWriter(Stream stream, Encoding encoding) : base(stream, encoding) { }
    public CustomWriter(string filename, Encoding encoding) : base(filename, encoding) { }

    public List<string> FieldList { get; set; }

    private string _localName;

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        if (!FieldList.Contains(localName))
            base.WriteStartElement(prefix, localName, ns);
        else
            _localName = localName;
    }

    public override void WriteString(string text)
    {
        if (!FieldList.Contains(_localName))
            base.WriteString(text);
    }

    public override void WriteEndElement()
    {
        if (!FieldList.Contains(_localName))
            base.WriteEndElement();
        else
            _localName = null;
    }
}

Используйте его следующим образом:

var data = new TestObj();

var serializer = new DataContractSerializer(
    typeof(TestObj), null, 0x7FFFFFFF, false, true, null);

using (var writer = new CustomWriter(Console.Out)) // Specify filename or stream instead
{
    writer.Formatting = Formatting.Indented;
    writer.FieldList = new List<string> { "field1", "field3" }; // Specify fields to ignore
    serializer.WriteObject(writer, data);
}

Просто укажите список полей, которые следует игнорировать в FieldListproperty.

Конечно, таким образом DataContractSerializer будет промежуточно создавать xml со всеми элементами, содержащимися в классе. И только после этого наш пользовательский писатель отфильтрует их. Но это произойдет на лету, очень быстро и эффективно.

0 голосов
/ 13 октября 2019

После того, как вы сериализовали весь объект, вы можете затем разделить его, используя Linq to XML .

О, я даже нашел пример, как это сделать в Как разделитьXML-файл на несколько XML-файлов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...