Home > front end >  How to resolve System.Xml.Schema.XmlSchemaValidationException
How to resolve System.Xml.Schema.XmlSchemaValidationException

Time:01-13

I am trying to validate XML using an online XSD. Here is my current code for my controller:

using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using Microsoft.AspNetCore.Mvc;

namespace EINV.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class XmlController : Controller
    {   
        [HttpPost]
        public IActionResult ValidateXml2(IFormFile xmlFile, string xsdUrl)
        {

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.XmlResolver = new XmlXsdResolver();     // Need this for resolving include and import
            settings.ValidationType = ValidationType.Schema; // This might not be needed, I am using same settings to validate the input xml
            //settings.DtdProcessing = DtdProcessing.Parse;    // I have an include that is dtd. maybe I should prohibit dtd after I compile the xsd files.
            settings.Schemas.Add(null, xsdUrl); // https://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd
            settings.Schemas.Compile();
            settings.ValidationType = ValidationType.Schema;

            XmlReader reader = XmlReader.Create(xmlFile.OpenReadStream(), settings, "https://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/");
            XmlDocument document = new XmlDocument();
            document.Load(reader);

            ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler);

            // the following call to Validate succeeds.
            document.Validate(eventHandler);
            // Load the XML file into an XmlDocument

            return Ok();
        }

        protected class XmlXsdResolver : XmlUrlResolver
        {
            public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
            {
                return base.GetEntity(absoluteUri, role, ofObjectToReturn);
            }
        }

        private void ValidationEventHandler(object? sender, ValidationEventArgs? e)
        {
            if (e?.Severity == XmlSeverityType.Error)
            {
                throw new Exception("XML validation error: "   e.Message);
            }
        }
    }
}

I have referenced several other posts in trying to resolve this, such as the following:

How can I resolve the schemaLocation attribute of an .XSD when all of my .XSD's are stored as resources?

Compiling two embedded XSDs: error "Cannot resolve 'schemaLocation' attribute

Validating xml against an xsd that has include and import in c#

But always end up with the same error:

System.Xml.Schema.XmlSchemaValidationException: 'The 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2:UBLExtensions' element is not declared.'

The XML that I am using, which I downloaded into a file and upload through my SWAGGER when calling the controller, is located here: https://docs.oasis-open.org/ubl/os-UBL-2.1/xml/UBL-Invoice-2.1-Example.xml

The XSD that I am using is located here: https://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd

CodePudding user response:

I think you need to set settings.Schemas.XmlResolver = new XmlUrlResolver(); as well, as the flag settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; before.

That might get you only further as I think some schemas (e.g. for signatures) are imported and not found. So in the end you will need to make sure you have local copies of those schemas and have your resolver use the local copies.

  • Related