问题
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