PeejayAdams Ответов: 2

Сериализация XML-фрагмента на языке Си#


Мне нужен способ сериализации универсальных объектов в XML-фрагменты.

Фрагменты будут вставлены в другие XML-документы, и поэтому мне нужен результат, который будет выглядеть примерно так:

<firstProperty>firstPropertyValue</firstProperty>
<secondProperty>secondPropertyValue</secondProperty>


в отличие от:

<className xlmns="Whatever">
    <firstProperty>firstPropertyValue</firstProperty>
    <secondProperty>secondPropertyValue</secondProperty>
</className>


Мой код выглядит примерно так:

private static string GetRow<T>(object _data)
{
    StringBuilder xml = new StringBuilder();

    T data = (T)_data;

    XmlWriterSettings settings = new XmlWriterSettings();

    settings.OmitXmlDeclaration = true;
    settings.ConformanceLevel = ConformanceLevel.Fragment;

    XmlSerializer serialiser = new XmlSerializer(typeof(T));
    XmlWriter writer = XmlWriter.Create(xml, settings);

    serialiser.Serialize(writer, data, null);

    return xml.ToString();

}


Моя первая мысль состояла в том, что параметр OmitXmlDeclaration выполнит эту работу - это не так, если вы не установите ConformanceLevel на Fragment. Проблема в том, что как только я устанавливаю уровень соответствия, я получаю следующую ошибку времени выполнения:

"
Цитата:
"WriteStartDocument не может быть вызван для писателей, созданных с помощью ConformanceLevel.Фрагмент."


Так что, похоже, что XmlSerializer.Serialize() вызывает WriteStartDocument независимо от того, что уровень соответствия установлен на Fragment, а не Document.

Я подозреваю, что самый простой способ обойти это-написать свой собственный сериализатор, но мне было бы интересно узнать, есть ли на самом деле способ успешно создать фрагмент из класса XmlSerializer.

2 Ответов

Рейтинг:
12

D Sarthi Maheshwari

Если ваша проблема заключается только в том, чтобы получить фрагмент. Одним из способов сделать это является:

var reader = XmlReader.Create(YOUR_SERIALIZED_FILE_NAME);
читатель.Читать();
читатель.ReadToFollowing(ИМЯ_УЗЛА);

Затем используйте любой из них.ReadOuterXml() или reader.ReadInnerXml() в соответствии с требованием ur.

Надеюсь, это поможет.


PeejayAdams

Это было то вдохновение, которое мне было нужно, спасибо!

Я изменил свой код, чтобы прикрепить XmlReader к файловому потоку XmlWriter, и он делает именно то, что я хочу:

частная статическая строка GetRow<t>(object _data)
{
То StringBuilder XML в новое окно инструментов();
MemoryStream stream = Новый Поток памяти();

T data = (T)_data;

XmlSerializer serializer = новый XmlSerializer(typeof(T));

XmlWriter writer = XmlWriter.Создать(поток);

сериализатор.Сериализация(writer, data, null);
писатель.Закрывать();

течение.Seek(0, SeekOrigin.Begin);

XmlReader xmlReader = XmlReader.Создать(поток);

объект XmlReader.MoveToContent();

верните xmlReader.ReadInnerXml();
}

Рейтинг:
0

gorilla129

string FragmentXml(object o) {
    var doc = new XmlDocument();
    using var writer = doc.CreateNavigator().AppendChild();
    new XmlSerializer(o.GetType()).Serialize(writer, o);
    return doc.DocumentElement.InnerXml;
}