Этот пост 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?
}
}
(Этот код также не проверяется.)