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

如何解决XML检查中的System.Xml.XmlException: '根元素缺失'错误?

解决XML验证时“根元素缺失”的问题

错误原因

你代码里的核心问题是复用了已被读取完毕的StringReader实例:

  • 第一次用srStringReader创建XmlReader并执行InferSchema时,已经把整个XML内容读完,流的位置停在了末尾。
  • 第二次再用同一个srStringReader创建reader1时,没有任何内容可以读取,自然触发“根元素缺失”的异常。

修复方案

方案1:重新创建StringReader

每次读取前新建一个StringReader实例,确保每次都从XML内容的开头读取:

using System.Text;
using System.Xml;
using System.Xml.Schema;
using XmlParser3;

string doc = Resource1.Payload;

XmlDocument document = new XmlDocument();
var errors = new StringBuilder();

// 第一次读取用于推断Schema
XmlReaderSettings settings = new XmlReaderSettings();
settings.CloseInput = true;
settings.ValidationType = ValidationType.Schema;
using (var srForSchema = new StringReader(doc))
using (XmlReader reader = XmlReader.Create(srForSchema))
{
    XmlSchemaSet schemaSet = new XmlSchemaSet();
    XmlSchemaInference schema = new XmlSchemaInference();
    schemaSet = schema.InferSchema(reader);

    settings.Schemas.Add(schemaSet);
    settings.ValidationFlags =
        XmlSchemaValidationFlags.ReportValidationWarnings |
        XmlSchemaValidationFlags.ProcessIdentityConstraints |
        XmlSchemaValidationFlags.ProcessInlineSchema |
        XmlSchemaValidationFlags.ProcessSchemaLocation;
}

// 第二次读取用于加载和验证XML,新建StringReader
using (var srForValidation = new StringReader(doc))
using (var reader1 = XmlReader.Create(srForValidation, settings))
{
    document.Load(reader1);
    document.Validate((o, e) =>
    {
        errors.AppendLine(e.Exception?.Message ?? e.Message);
    });
}

Console.WriteLine(errors);

方案2:用MemoryStream重置读取位置

StringReader没法直接重置位置,可以换成MemoryStream承载XML内容,通过Seek方法把流指针移回开头:

using System.Text;
using System.Xml;
using System.Xml.Schema;
using XmlParser3;

string doc = Resource1.Payload;
byte[] xmlBytes = Encoding.UTF8.GetBytes(doc);
using (var ms = new MemoryStream(xmlBytes))
{
    XmlDocument document = new XmlDocument();
    var errors = new StringBuilder();

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.CloseInput = false; // 不关闭流,留着复用
    settings.ValidationType = ValidationType.Schema;
    
    // 第一次读取推断Schema
    using (XmlReader reader = XmlReader.Create(ms))
    {
        XmlSchemaSet schemaSet = new XmlSchemaSet();
        XmlSchemaInference schema = new XmlSchemaInference();
        schemaSet = schema.InferSchema(reader);

        settings.Schemas.Add(schemaSet);
        settings.ValidationFlags =
            XmlSchemaValidationFlags.ReportValidationWarnings |
            XmlSchemaValidationFlags.ProcessIdentityConstraints |
            XmlSchemaValidationFlags.ProcessInlineSchema |
            XmlSchemaValidationFlags.ProcessSchemaLocation;
    }

    // 重置流到开头
    ms.Seek(0, SeekOrigin.Begin);

    // 第二次读取验证XML
    using (var reader1 = XmlReader.Create(ms, settings))
    {
        document.Load(reader1);
        document.Validate((o, e) =>
        {
            errors.AppendLine(e.Exception?.Message ?? e.Message);
        });
    }

    Console.WriteLine(errors);
}

关于“逐行检查XML格式合规”的补充

如果你的需求是只检查XML语法格式(不是基于Schema的验证),可以调整配置关闭Schema验证,直接逐行检查:

using System.Text;
using System.Xml;
using System.Xml.Schema;
using XmlParser3;

string doc = Resource1.Payload;
var errors = new StringBuilder();

XmlReaderSettings syntaxCheckSettings = new XmlReaderSettings();
syntaxCheckSettings.ValidationType = ValidationType.None;
syntaxCheckSettings.ValidationEventHandler += (o, e) =>
{
    errors.AppendLine($"行 {e.Exception.LineNumber}:{e.Message}");
};

using (var sr = new StringReader(doc))
using (XmlReader reader = XmlReader.Create(sr, syntaxCheckSettings))
{
    try
    {
        while (reader.Read()) { }
    }
    catch (XmlException ex)
    {
        errors.AppendLine($"行 {ex.LineNumber}:{ex.Message}");
    }
}

Console.WriteLine(errors);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 03:35:34