使用架构验证 XML 文件,但浏览整个文档,然后显示错误?

问题描述 投票:0回答:1

我可以使用架构 (XSD) 验证 XML,但它会在第一个错误/故障处停止,并且不会从那里继续。 有没有办法遍历整个 XML 文件?

至少我的猜测是阅读部分,但找不到另一个来做到这一点。

using (XmlReader reader = XmlReader.Create(xmlPath, settings)) 
{
        while (reader.Read()) { }
}

完整代码

public class Program
{
    private static List<string> errList = new();

    static void ValidationEventHandler(object sender, ValidationEventArgs e)
    {
        if (e.Severity == XmlSeverityType.Warning)
        {
            errList.Add("WARNING: " + e.Message);
        }
        else if (e.Severity == XmlSeverityType.Error)
        {
            errList.Add("ERROR: " + e.Message);
        }
    }

    static void Main(string[] args)
    {
        string xmlPath = @"path_here";
        string schemePath = @"path_here";

        XmlReaderSettings settings = new();

        // Need this for resolving include and import
        settings.Schemas.XmlResolver = new XmlUrlResolver();

        // This might not be needed, I am using same settings to validate the input xml
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
        settings.Schemas.Add("namespace_name_here", schemePath);
        settings.ValidationEventHandler += ValidationEventHandler;
        settings.Schemas.Compile();


        // Create an XmlReader for the XML file
        using (XmlReader reader = XmlReader.Create(xmlPath, settings)) 
        {
            while (reader.Read()) { }
        }

        if (errList.Any()) 
        {
            foreach (string msg in errList) { Console.WriteLine(msg); }
        }


        Console.ReadKey();
    }
}

--- 编辑 ---

我正在使用一大组 XSD,并且在其他 XSD 中导入了右侧和左侧。 不同的命名空间中有 22 个 XSD =),但找不到将这些包含在此处的好方法吗? 这是 SFTI.se 上包含 XSD 的文件的链接。 https://sfti.se/download/18.3a0a1c2218723106f76484f0/1680520279996/Svefaktura1_Arkiv%202023-02-23.zip 文件内的 Zip:“XML-Schema for Svefaktura 1.0.zip”

文件夹“SvefakturaExempelfiler”中有 exmaple XML 文件

c# xml xsd schema
1个回答
0
投票

我将您的代码变成了一个最小但完整的示例,以通过简单的 XML 实例文档和简单的 XML 模式重现所谓的未能显示多个错误的情况:

using System;
using System.Xml;
using System.Xml.Schema;
using System.Collections.Generic;
using System.Linq;
using System.IO;
                    
public class Program
{
   private static List<string> errList = new();

    static void ValidationEventHandler(object sender, ValidationEventArgs e)
    {
        if (e.Severity == XmlSeverityType.Warning)
        {
            errList.Add("WARNING: " + e.Message);
        }
        else if (e.Severity == XmlSeverityType.Error)
        {
            errList.Add("ERROR: " + e.Message);
        }
    }

    static void Main(string[] args)
    {
        string xml = @"<root>
          <item>a</item>
          <item>1</item>
          <item>b</item>
          <item>2</item>
        </root>";
        
        string xsd = @"<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"">
  <xs:element name=""root"">
   <xs:complexType>
     <xs:sequence>
       <xs:element name=""item"" type=""xs:decimal"" maxOccurs=""unbounded""/>
     </xs:sequence>
   </xs:complexType>
  </xs:element>
</xs:schema>";

        XmlReaderSettings settings = new();

        // Need this for resolving include and import
        settings.Schemas.XmlResolver = new XmlUrlResolver();

        // This might not be needed, I am using same settings to validate the input xml
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
        settings.Schemas.Add(null, XmlReader.Create(new StringReader(xsd)));
        settings.ValidationEventHandler += ValidationEventHandler;
        settings.Schemas.Compile();


        // Create an XmlReader for the XML file
        using (XmlReader reader = XmlReader.Create(new StringReader(xml), settings)) 
        {
            while (reader.Read()) { }
        }

        if (errList.Any()) 
        {
            foreach (string msg in errList) { Console.WriteLine(msg); }
        }


        Console.ReadKey();
    }
}

输出:

ERROR: The 'item' element is invalid - The value 'a' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:decimal' - The string 'a' is not a valid Decimal value.
ERROR: The 'item' element is invalid - The value 'b' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:decimal' - The string 'b' is not a valid Decimal value.

因此发现并报告了这两个错误。

当然,与任何验证一样,如果您有一个完全错误的实例或元素,那么通常无法从仅声明第一个错误中恢复。

考虑显示一个 XML 和 XSD 示例,其中您的代码无法重现您期望的错误,以便我们判断是否可能。

© www.soinside.com 2019 - 2024. All rights reserved.