Simultaneously writing and validating XML

丶灬走出姿态 提交于 2020-01-03 17:47:36

问题


I have a Write method that serializes objects which use XmlAttributes. It's pretty standard like so:

private bool WriteXml(DirectoryInfo dir)
{
    var xml = new XmlSerializer(typeof (Composite));
    _filename = Path.Combine(dir.FullName, _composite.Symbol + ".xml");
    using (var xmlFile = File.Create(_filename))
    {
          xml.Serialize(xmlFile, _composite);
    }
    return true;
}

Apart from trying to read the file I have just written out (with a Schema validator), can I perform XSD validation WHILE the XML is being written?

I can mess around with memory streams before writing it to disk, but it seems in .Net there is usually an elegant way of solving most problems.


回答1:


The way I've done it is like this for anyone interested:

public Composite Read(Stream stream)
{
    _errors = null;
    var settings = new XmlReaderSettings();
    using (var fileStream = File.OpenRead(XmlComponentsXsd))
    {
        using (var schemaReader = new XmlTextReader(fileStream))
        {
            settings.Schemas.Add(null, schemaReader);
            settings.ValidationType = ValidationType.Schema;
            settings.ValidationEventHandler += OnValidationEventHandler;
            using (var xmlReader = XmlReader.Create(stream, settings))
            {
                var serialiser = new XmlSerializer(typeof (Composite));
                return (Composite) serialiser.Deserialize(xmlReader);
            }
        }
    }
}

private ValidationEventArgs _errors = null;
private void OnValidationEventHandler(object sender, ValidationEventArgs validationEventArgs)
{
    _errors = validationEventArgs;
}

Then instead of writing the XML to file, using a memory stream do something like:

private bool WriteXml(DirectoryInfo dir)
{
    var xml = new XmlSerializer(typeof (Composite));
    var filename = Path.Combine(dir.FullName, _composite.Symbol + ".xml");
    // first write it to memory
    var memStream = new MemoryStream();
    xml.Serialize(memStream, _composite);
    memStream.Position = 0;
    Read(memStream);
    if (_errors != null)
    {
        throw new Exception(string.Format("Error writing to {0}. XSD validation failed : {1}", filename, _errors.Message));
    }
    memStream.Position = 0;
    using (var outFile = File.OpenWrite(filename))
    {
        memStream.CopyTo(outFile);
    }
    memStream.Dispose();
    return true;
}

That way you're always validating against the schema before anything is written to disk.



来源:https://stackoverflow.com/questions/13963920/simultaneously-writing-and-validating-xml

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!