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

.NET中验证XML时忽略schemaLocation,强制使用指定XSD

强制使用指定XSD验证XML,忽略xml中的schemaLocation属性

我实现了一个简单的XML文件验证逻辑,当XML文件不包含schemaLocation属性时验证正常,但一旦该属性存在,验证逻辑就会忽略我指定的XSD文件,转而使用该属性引用的schema。需求是:无论XML是否包含schemaLocation,都始终使用SchemaSet中指定的XSD进行验证。

原验证代码

public static bool Validate (string xmlFile, string xsdFile)
{
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.Schemas.Add("", xsdFile);
    settings.ValidationType = ValidationType.Schema;

    using (XmlReader reader = XmlReader.Create(xmlFile, settings))
    {
        XmlDocument document = new XmlDocument();
        document.Load(reader);
        System.Console.WriteLine(settings.Schemas.Count);

        ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler);

        // the following call to Validate succeeds.
        document.Validate(eventHandler);
    }

    return true;    
}

static void ValidationEventHandler(object sender, ValidationEventArgs e)
{
    switch (e.Severity)
    {
        case XmlSeverityType.Error:
            throw new System.Exception(e.Message);                                    
    }
}

测试场景

我的目标是用指定XSD验证不同XML,理应始终抛出“Document元素不被允许”的错误:

无schemaLocation的XML(验证正常)

<?xml version="1.0" encoding="UTF-8"?>
<Document>
  <BkToCstmrDbtCdtNtfctn xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02">
    <GrpHdr>
      <MsgId>TEST-fbbd57f6285403ad2b146ccbe8ceed</MsgId>
      <CreDtTm>2017-08-18T10:55:35.906+02:00</CreDtTm>

带schemaLocation的XML(未触发预期错误)

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02 camt.054.001.02.xsd">
  <BkToCstmrDbtCdtNtfctn xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02">
    <GrpHdr>
      <MsgId>TEST-fbbd57f6285403ad2b146ccbe8ceed</MsgId>
      <CreDtTm>2017-08-18T10:55:35.906+02:00</CreDtTm>

解决方案

要强制使用指定XSD,需要做两处关键修改:

  • 禁用ProcessSchemaLocation验证标志,阻止系统自动加载xml中指定的外部schema
  • 调用XmlDocument.Validate时明确传入我们的SchemaSet,确保验证使用指定的XSD

修改后的代码

public static bool Validate(string xmlFile, string xsdFile)
{
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.Schemas.Add("", xsdFile);
    settings.ValidationType = ValidationType.Schema;
    // 禁用自动处理xml中的schemaLocation属性,避免加载外部schema
    settings.ValidationFlags &= ~XmlSchemaValidationFlags.ProcessSchemaLocation;

    using (XmlReader reader = XmlReader.Create(xmlFile, settings))
    {
        XmlDocument document = new XmlDocument();
        document.Load(reader);

        ValidationEventHandler eventHandler = ValidationEventHandler;

        // 明确指定使用预先配置的SchemaSet进行验证
        document.Validate(settings.Schemas, eventHandler);
    }

    return true;
}

static void ValidationEventHandler(object sender, ValidationEventArgs e)
{
    if (e.Severity == XmlSeverityType.Error)
    {
        throw new Exception(e.Message);
    }
}

关键说明

  1. 禁用ProcessSchemaLocation:默认情况下,XmlReaderSettings会启用ProcessSchemaLocation标志,自动解析并加载xml中xsi:schemaLocation指定的schema。通过settings.ValidationFlags &= ~XmlSchemaValidationFlags.ProcessSchemaLocation可以关闭这一行为。
  2. 指定SchemaSet验证:调用document.Validate(settings.Schemas, eventHandler)时,明确传入我们添加了指定XSD的SchemaSet,确保验证逻辑完全使用我们指定的规则,不受文档自身schema信息影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:54:55