validate xml during serialization
Asked Answered
D

0

2

This post https://mcmap.net/q/957285/-xmlserializer-validation gives a solution on how to validate an xml during deserialization. It also says that similar code can be written for serialization, but I was not able to figure it out.

Can someone give a hint?

I want to do the validation during serialization, so that, if the validation fails at some point, the serialization stops immediately.


Based on the linked answer my deserialization code, where validation takes place, looks like this:

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);
        }
    }
}

The class top is the class representing the root element of my xml schema; I created the classes with xsd.exe.

This works perfectly; when the xml does not conform to the schema, I get an XmlSchemaValidationException.


In order to transfer this approach to my curent serialization code (where no validation takes place), which looks like this

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

, I would need to put the XmlReader somewhere, since it's the XmlReader that is needed for validation. But where and how? The XmlReader.Create method takes a TextReader or a Stream as input, so I assume I need to have already put something into the stream before the XmlReader can read it. So

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

won't validate the generated xml since the stream is still empty when it goes through the XmlReader. The stream will only be filled AFTER the call of _topSerializier.Serialize, so doing the reading after it makes kind of sense. But then, what to put in there?

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

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

(This code also does not validate.)

Dampen answered 6/11, 2018 at 9:17 Comment(4)
The XmlReader Create also takes a string filename : XmlReader reader = XmlReader.Create(filename). You can use a StreamReader sReader = new StreamReader (filename); XmlReader reader = XmlReader.Create(sReader) or a StringReader : StringReader strReader = new StringReader(string); XmlReader reader = XmlReader.Create(strReader);Whipcord
@Whipcord Yes, but to use these Create methods, I would first serialize (completely) and only afterwards validate. That is not what I want; I want to validate DURING serialization so that, if the validation fails, the serialization stops immediately.Dampen
Not all errors can be validated DURING Serialization. XML errors like missing end tags will cause exception in the middle. Schema checks will only check in the middle if values are out of range or missing (when required). The Create only opens the file and does not do any validation until the serialize/deserialize method..Whipcord
Seems like this is not possible after all. Simultaneously writing and validating XML and How can I validate the output of XmlSerializer? only give workarounds. Can XmlWriter validate against schema also? (.NET 2.0) also only suggests a workaround. And XmlWriterSettings lacks the Schemas property of XmlReaderSettings.Schulman

© 2022 - 2024 — McMap. All rights reserved.