为什么我的 xsd 没有在 C 中自动引发必填字段异常#

Why my xsd is not automatically raising required field exception in C#

提问人:Ayushi Ramsurn 提问时间:10/11/2023 最后编辑:Ayushi Ramsurn 更新时间:10/11/2023 访问量:50

问:

这是我的XML

<?xml version="1.0" encoding="utf-8"?>
<Zones xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.keaneaustralia.com/Nts" xsi:schemaLocation="http://schemas.keaneaustralia.com/Nts Zones.xsd" version="1" major_version="434" minor_version="0" start_date="2023-07-09T00:00:00+10:00">
<Record long_desc="City Saver Zone"/>
<Record logical="2" physical="1" short_desc="Zone 1" long_desc="Zone 1" is_city_saver="Yes" />
<Record logical="3" physical="2" short_desc="Zone 2" long_desc="Zone 2" is_city_saver="false" />
<Record logical="dt" physical="3" short_desc="Zone 3" long_desc="Zone 3" is_city_saver="false" />
<Record logical="5" physical="4" short_desc="Zone 4" long_desc="Zone 4" is_city_saver="false" />
<Record logical="6" physical="5" short_desc="Zone 5" long_desc="Zone 5" is_city_saver="false" />
</Zones>

这是我的XSD

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://schemas.keaneaustralia.com/Nts" elementFormDefault="qualified" targetNamespace="http://schemas.keaneaustralia.com/Nts" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Zones" nillable="true" type="tns:ZoneCollection" />
<xs:complexType name="ZoneCollection">
<xs:complexContent mixed="false">
<xs:extension base="tns:DataElementOfZone" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="DataElementOfZone">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Record" type="tns:Zone" />
</xs:sequence>
<xs:attribute name="version" type="xs:int" use="required" />
<xs:attribute name="major_version" type="xs:int" use="required" />
<xs:attribute name="minor_version" type="xs:int" use="required" />
<xs:attribute name="start_date" type="xs:dateTime" use="required" />
<xs:attribute default="false" name="is_delta" type="xs:boolean" />
<xs:attribute default="0" name="delta_major_version" type="xs:int" />
<xs:attribute default="0" name="delta_minor_version" type="xs:int" />
</xs:complexType>
<xs:complexType name="Zone">
<xs:attribute name="logical" type="xs:unsignedByte" use="required" />
<xs:attribute name="physical" type="xs:unsignedByte" use="required" />
<xs:attribute name="short_desc" type="xs:string" />
<xs:attribute name="long_desc" type="xs:string" />
<xs:attribute name="is_city_saver" type="xs:boolean" use="required" />
</xs:complexType>
</xs:schema>

文件正在通过验证,并且没有引发任何错误。当我检查调试模式时,attributeSchemaInfo.Below 是验证 xml 的函数,存在 null 引用异常。它不会引发字段 is_city_saver 的逻辑属性和类型错误所需的异常,该字段仅期望布尔值:true 和 false,而不是 yes 和 no。


 private static bool ValidateXmlAgainstXsd(string xmlFilePath, string xsdFilePath, ILogger fileLogger)
        {
            try
            {
                int numErreur = 0;
                XmlSchemaSet schemaSet = new XmlSchemaSet();
                schemaSet.Add(null, xsdFilePath);
                schemaSet.Compile();

 

                XmlReaderSettings settings = new XmlReaderSettings();
                settings.Schemas.Add(schemaSet);
                settings.ValidationType = ValidationType.Schema;
                settings.ValidationFlags =
                XmlSchemaValidationFlags.ReportValidationWarnings |
                XmlSchemaValidationFlags.ProcessIdentityConstraints |
                XmlSchemaValidationFlags.ProcessInlineSchema;
                settings.ValidationEventHandler += (sender, e) =>
                {
                   LogValidationError(xmlFilePath, e.Message, e.Exception, e.Exception.LineNumber, e.Exception.LinePosition, e.Severity, fileLogger, ref numErreur);
                };

 

                using (XmlReader reader = XmlReader.Create(xmlFilePath, settings))
                {
                    while (reader.Read())
                    {
                        //process code
                     }
                }
                return numErreur > 0 ? false : true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error validating XML '{xmlFilePath}' against XSD '{xsdFilePath}': {ex.Message}");
                return false;
            }
        }

 
       

C# XML XSD 验证 xmlReader

评论

0赞 jdweng 10/11/2023
架构同时具有 Zone 和 Zones。xml 只有区域。
0赞 Ayushi Ramsurn 10/17/2023
此属性指定“Record”元素应符合的数据类型或复杂类型。在本例中,它引用由“tns”表示的命名空间中名为“Zone”的类型。

答:

0赞 Yitzhak Khabinsky 10/11/2023 #1

我稍微修改了您的代码,并注释掉/删除了调用。LogValidationError()

XSD 验证正在工作!请看下文。

我的猜测是问题出在注释掉的 .LogValidationError()

c#

void Main()
{   
    string xmlFilePath = @"e:\Temp\Zones.xml";
    string xsdFilePath = @"e:\Temp\Zones.xsd";
    
    ValidateXmlAgainstXsd(xmlFilePath, xsdFilePath);
}

private static bool ValidateXmlAgainstXsd(string xmlFilePath, string xsdFilePath)
{
    try
    {
        int numErreur = 0;
        XmlSchemaSet schemaSet = new XmlSchemaSet();
        schemaSet.Add(null, xsdFilePath);
        schemaSet.Compile();



        XmlReaderSettings settings = new XmlReaderSettings();
        settings.Schemas.Add(schemaSet);
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationFlags =
        XmlSchemaValidationFlags.ReportValidationWarnings |
        XmlSchemaValidationFlags.ProcessIdentityConstraints |
        XmlSchemaValidationFlags.ProcessInlineSchema;
        settings.ValidationEventHandler += (sender, e) =>
        {
            //LogValidationError(xmlFilePath, e.Message, e.Exception, e.Exception.LineNumber, e.Exception.LinePosition, e.Severity, fileLogger, ref numErreur);
            Console.WriteLine(e.Message);
        };



        using (XmlReader reader = XmlReader.Create(xmlFilePath, settings))
        {
            while (reader.Read())
            {
                //process code
            }
        }
        return numErreur > 0 ? false : true;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error validating XML '{xmlFilePath}' against XSD '{xsdFilePath}': {ex.Message}");
        return false;
    }
}

输出

The required attribute 'logical' is missing.
The required attribute 'physical' is missing.
The required attribute 'is_city_saver' is missing.
The 'is_city_saver' attribute is invalid - The value 'Yes' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:boolean' - The string 'Yes' is not a valid Boolean value.
The 'logical' attribute is invalid - The value 'dt' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:unsignedByte' - The string 'dt' is not a valid Byte value.

评论

0赞 Ayushi Ramsurn 10/17/2023
您使用的是哪个版本的 Visual Studio。它不适用于我使用 Visual Studio 2017 的地方
0赞 Yitzhak Khabinsky 10/17/2023
它与 Visual Studio 无关。我使用 LINQPad 来测试 c# 代码。您的 XML/XSD 可能与您在问题中作为示例提供的 XML/XSD 不同。
0赞 Ayushi Ramsurn 10/18/2023
好的,这是我这边的错误。我错误地将 XSD 路径传递给函数。感谢您的帮助。
0赞 Yitzhak Khabinsky 10/18/2023
@AyushiRamsurn,很高兴听到现在一切都在为你工作。请不要忘记接受答案。