You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决System.Xml.Schema.XmlSchemaValidationException异常

UBL XML验证失败问题解决

问题场景

我尝试用ASP.NET Core控制器验证UBL格式的XML文件,使用官方提供的XSD,但始终触发以下验证错误:

System.Xml.Schema.XmlSchemaValidationException: '未声明‘urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2:UBLExtensions’元素。'

使用的XML是UBL官方示例发票文件,XSD是UBL官方的发票主XSD文件。

控制器代码

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();     // 用于解析include和import
            settings.ValidationType = ValidationType.Schema;
            //settings.DtdProcessing = DtdProcessing.Parse;    // 有一个dtd的include,可能编译XSD后需要禁用dtd
            settings.Schemas.Add(null, xsdUrl); // 传入UBL发票主XSD的URL
            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);

            document.Validate(eventHandler);

            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验证错误: " + e.Message);
            }
        }
    }
}

问题原因

UBL的主XSD文件依赖多个子XSD(比如CommonExtensionComponents等),虽然代码中设置了XmlResolver,但在线加载时,依赖的XSD可能没有被正确解析并添加到验证架构集合中,或者ASP.NET Core环境的网络限制导致无法下载依赖文件。

修复方案

方案1:本地缓存UBL所有XSD文件

UBL官方XSD包含多个相互引用的文件,在线加载容易出现解析问题。建议直接下载整套UBL 2.1的XSD文件到本地项目,然后通过相对路径引用主XSD,避免网络请求的不确定性。

方案2:优化架构加载逻辑

使用XmlSchemaSet自动解析依赖的XSD,替换原来的XmlReaderSettings.Schemas方式,确保所有依赖架构被正确加载:

[HttpPost]
public IActionResult ValidateXml2(IFormFile xmlFile, string xsdUrl)
{
    XmlSchemaSet schemaSet = new XmlSchemaSet();
    // 使用默认XmlUrlResolver解析依赖
    schemaSet.XmlResolver = new XmlUrlResolver();
    // 添加主XSD,XmlSchemaSet会自动递归加载所有import/include的依赖文件
    schemaSet.Add(null, xsdUrl);
    // 编译架构集
    schemaSet.Compile();

    // 加载待验证的XML
    XmlDocument document = new XmlDocument();
    using (var stream = xmlFile.OpenReadStream())
    {
        document.Load(stream);
    }

    // 绑定架构集并验证
    document.Schemas = schemaSet;
    document.Validate((sender, e) =>
    {
        if (e.Severity == XmlSeverityType.Error)
        {
            throw new Exception($"XML验证错误: {e.Message}");
        }
    });

    return Ok();
}

方案3:检查网络访问权限

如果必须在线加载XSD,需要确保ASP.NET Core应用有访问外部网络的权限(比如在容器或服务器环境中,网络策略是否允许访问目标域名)。同时可以自定义XmlResolver添加日志,排查是否成功下载了依赖的XSD文件。


内容的提问来源于stack exchange,提问作者randomvoice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:31:03