Single-pass Read and Validate XML vs referenced XSD in C#

吃可爱长大的小学妹 提交于 2019-12-02 07:58:19

You're very close with your solution; what you need to do is to use a validating reader to load your XML; this way the validation is done with your loading, in one pass; validation errors will not stop you from loading the document.

These are the high level steps that I usually use with a ValidateXml helper function; it all starts with a compiled XmlSchemaSet:

public bool ValidateXml(XmlSchemaSet xset)

I set the reader settings (which you did, too):

XmlReaderSettings settings = new XmlReaderSettings { ValidationType = ValidationType.Schema, Schemas = xset, ConformanceLevel = ConformanceLevel.Document };
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
// Use your helper class that collects validation events. 
XsdUtils.Utils.SmartValidationHandler svh = new XsdUtils.Utils.SmartValidationHandler(Paschi.Xml.DefaultResolver.Instance);
settings.ValidationEventHandler += svh.ValidationCallbackOne;

Then I get a reader:

XmlReader xvr = XmlReader.Create(filename, settings);

Then I read the file, which brings the validation in:

XmlDocument xdoc = new XmlDocument();
xdoc.Load(xvr);

Your validation handler has the results now; one thing I also do is to ensure that the document element that was loaded, actually has a corresponding global element definition in the xml schema set.

XmlQualifiedName qn = XmlQualifiedName.Empty;
if (xdoc.DocumentElement != null)
{
        if (string.IsNullOrEmpty(xdoc.DocumentElement.NamespaceURI))
        {
              qn = new XmlQualifiedName(xdoc.DocumentElement.LocalName);
        }
        else
        {
               qn = new XmlQualifiedName(xdoc.DocumentElement.LocalName, xdoc.DocumentElement.NamespaceURI);
         }
}
return !(svh.HasError || qn.IsEmpty || (!xset.GlobalElements.Contains(qn)));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!