Validating XML on XSD with the error line numbers

前端 未结 6 1029
盖世英雄少女心
盖世英雄少女心 2021-01-04 15:19

Is there any way to validate an XML file on an XSD schema with the output of the error line numbers?

The XmlReader reader doesn\'t allow line numbers, it shows only

6条回答
  •  一生所求
    2021-01-04 15:33

    Woah, rather tricky this XSD stuff, I'm also new :)

    As it was said before the position information gets lost in the XmlDocument.

    I got it finally running using the XmlReader in combination with XmlDocument:

    // xmlStream and xsdStream are open streams that 
    // point to the respective xml and xsd files
    public void ReadAndVerify(Stream xmlStream, Stream xsdStream)
    {
        // Read the scheme validation and compile it
        XmlSchemaSet schemaSet = new XmlSchemaSet();
    
        using (XmlReader r = XmlReader.Create(xsdStream)) 
        {
            schemaSet.Add(XmlSchema.Read(r, null));
        }
    
        schemaSet.CompilationSettings = new XmlSchemaCompilationSettings();
        schemaSet.Compile();
    
        // Setup the settings for the reader.
        // This includes the previously compiled schema
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.CloseInput = true;
    
        // This is the callback method see below
        settings.ValidationEventHandler += ValidationEventHandler;
    
        settings.ValidationType = ValidationType.Schema;
        settings.Schemas = schemaSet;  // <-- here the schema is set
    
        // To be honest, this is cut'n'paste. Not sure which flags are really required.
        settings.ValidationFlags =
                XmlSchemaValidationFlags.ReportValidationWarnings |
        XmlSchemaValidationFlags.ProcessIdentityConstraints |
        XmlSchemaValidationFlags.ProcessInlineSchema |
        XmlSchemaValidationFlags.ProcessSchemaLocation;
    
        // Now the validating reader is created
        using (XmlReader validatingReader = XmlReader.Create(xmlStream, settings)) 
        {
    
            // This has to be done BEFORE the validating while loop
            XmlDocument x = new XmlDocument();
            x.Load(validatingReader);
    
            // This is the validation loop
            while (validatingReader.Read()) ;
    
            // This is the client code that actually uses the XmlDocument nodes.
            XmlNode node = x[RootNode];
            ReadAllParameters(node);
        }
    }
    

    And the ValidationEventHandler:

    private void ValidationEventHandler(object sender, ValidationEventArgs e)
    {
        // This actually works with this approach
        string text = $"[Line: {e.Exception?.LineNumber}, Column: {e.Exception?.LinePosition}]: {e.Message}";
        switch (e.Severity) {
            case XmlSeverityType.Error:
                Logger.Error(text);
                break;
            case XmlSeverityType.Warning:
                Logger.Warn(e.Message);
                break;
        }
    }
    

    Life can be so simple ;-)

提交回复
热议问题