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

后端 未结 1 500
生来不讨喜
生来不讨喜 2021-01-28 11:37

I\'m trying to read the data from an XML file, validating it against the XSD it suggests, into a single data structure (such as XmlDocument). I have a solution, but it requires

相关标签:
1条回答
  • 2021-01-28 12:38

    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)));
    
    0 讨论(0)
提交回复
热议问题