проверить XML во время сериализации - PullRequest
0 голосов
/ 06 ноября 2018

Этот пост https://stackoverflow.com/a/1708614/5333340 дает решение о том, как проверить XML во время десериализации. В нем также говорится, что подобный код может быть написан для сериализации, но я не смог его выяснить.

Может кто-нибудь дать подсказку?

Я хочу выполнить проверку во время сериализации, чтобы в случае сбоя проверки в какой-то момент сериализация немедленно прекратилась.


Исходя из связанного ответа, мой код десериализации, где происходит проверка, выглядит следующим образом:

private static readonly XmlSerializer _topSerializer = new XmlSerializer(typeof(top));
private static readonly XmlSettings _settings = ...
    // same as in the linked post, only without `ValidationEventHandler` set

public static top Deserialize(Stream strm)
{
    using (StreamReader input = new StreamReader(strm))
    {
        using (XmlReader reader = XmlReader.Create(input, _settings))
        {
            return (top)_topSerializer.Deserialize(reader);
        }
    }
}

Класс top - это класс, представляющий корневой элемент моей XML-схемы; Я создал классы с помощью xsd.exe.

Это прекрасно работает; когда xml не соответствует схеме, я получаю XmlSchemaValidationException.


Чтобы перенести этот подход в мой текущий код сериализации (где проверка не выполняется), который выглядит следующим образом

public static void Serialize(top t, Stream strm)
{
    using (XmlWriter wr = XmlWriter.Create(strm))
    {
        _topSerializer.Serialize(wr, t);
    }
}

, мне нужно было бы куда-то поместить XmlReader, поскольку для проверки требуется XmlReader. Но где и как? Метод XmlReader.Create принимает TextReader или Stream в качестве входных данных, поэтому я предполагаю, что мне нужно уже что-то поместить в поток, прежде чем XmlReader сможет его прочитать. Так

using (XmlReader reader = XmlReader.Create(strm, _settings))
{
    using (XmlWriter wr = XmlWriter.Create(strm))
    {
        _topSerializer.Serialize(wr, t);
    }
}

не будет проверять сгенерированный xml, так как поток все еще пуст, когда он проходит через XmlReader. Поток будет заполнен только ПОСЛЕ вызова _topSerializier.Serialize, поэтому чтение после него имеет смысл. Но тогда, что туда положить?

using (XmlWriter wr = XmlWriter.Create(strm))
{
    _topSerializer.Serialize(wr, t);

    using (XmlReader reader = XmlReader.Create(strm, _settings))
    {
        // what to do here?
    }
}

(Этот код также не проверяется.)

...