0

XML ファイルの検証を必要とする WPF アプリケーションを作成しています。1 つ以上の XSD ファイルに対して XML を検証する次のクラスがあります。

public class XSDValidator
{
    public List<XmlSchema> Schemas { get; set; }
    public List<String> Errors { get; set; }
    public List<String> Warnings { get; set; }

    public XSDValidator()
    {
        Schemas = new List<XmlSchema>();
    }

    /// <summary>
    /// Add a schema to be used during the validation of the XML document
    /// </summary>
    /// <param name="schemaFileLocation">The file path for the XSD schema file to be added for validation</param>
    /// <returns>True if the schema file was successfully loaded, else false (if false, view Errors/Warnings for reason why)</returns>
    public bool AddSchema(string schemaFileLocation)
    {
        // Reset the Error/Warning collections
        Errors = new List<string>();
        Warnings = new List<string>();

        XmlSchema schema;

        if (!File.Exists(schemaFileLocation))
        {
            throw new FileNotFoundException("The specified XML file does not exist", schemaFileLocation);
        }

        using (var fs = new FileStream(schemaFileLocation, FileMode.Open))
        {
            schema = XmlSchema.Read(fs, ValidationEventHandler);
        }

        var isValid = !Errors.Any() && !Warnings.Any();

        if (isValid)
        {
            Schemas.Add(schema);
        }

        return isValid;
    }

    /// <summary>
    /// Perform the XSD validation against the specified XML document
    /// </summary>
    /// <param name="xmlLocation">The full file path of the file to be validated</param>
    /// <returns>True if the XML file conforms to the schemas, else false</returns>
    public bool IsValid(string xmlLocation)
    {
        if (!File.Exists(xmlLocation))
        {
            throw new FileNotFoundException("The specified XML file does not exist", xmlLocation);
        }

        using (var xmlStream = new FileStream(xmlLocation, FileMode.Open))
        {
            return IsValid(xmlStream);
        }
    }

    /// <summary>
    /// Perform the XSD validation against the supplied XML stream
    /// </summary>
    /// <param name="xmlStream">The XML stream to be validated</param>
    /// <returns>True is the XML stream conforms to the schemas, else false</returns>
    private bool IsValid(Stream xmlStream)
    {
        // Reset the Error/Warning collections
        Errors = new List<string>();
        Warnings = new List<string>();

        var settings = new XmlReaderSettings
        {
            ValidationType = ValidationType.Schema
        };
        settings.ValidationEventHandler += ValidationEventHandler;

        foreach (var xmlSchema in Schemas)
        {
            settings.Schemas.Add(xmlSchema);
        }

        var xmlFile = XmlReader.Create(xmlStream, settings);

        while (xmlFile.Read()) { }

        return !Errors.Any() && !Warnings.Any();
    }

    private void ValidationEventHandler(object sender, ValidationEventArgs e)
    {
        switch (e.Severity)
        {
            case XmlSeverityType.Error:
                Errors.Add(e.Message);
                break;
            case XmlSeverityType.Warning:
                Warnings.Add(e.Message);
                break;
        }
    }
}

上記のコードはオープンソースであり、ここで見つけることができます。今、それは次のように呼び出されます:

var validator = new XSDValidator();
validator.AddSchema(@"C:\code\xml\books.xsd");

foreach (CheckableListItem file in FileFullPathChecklist)
{
    if (file.IsChecked)
    {
        if (validator.IsValid(file.Filename)) 
        {
            ValidatedXMLFiles++;
        }
    }
}

XSD 検証のテストでは、4 つの XML ファイルを使用しています。そのうちの 1 つ はbooks.xml、ハードコードされたスキーマに対応していますbooks.xsd。他の 3 つは、他のソースから取得したランダムな XML ファイルであり、books.xsd. ただし、コードを実行するとValidatedXMLFiles、1 ではなく 4 の値が表示されます。

XSDValidatorクラスから考えられる限りのことを確認しました。にランダムな文字列を手動で追加しようとしましたが、その場合は falseErrorsを返しました。IsValid興味深いと思ったのは、スキーマ ファイル名を存在しない名前に変更しようとしたときに、予期TargetInvocationExceptionした の代わりに がスローされたFileNotFoundExceptionことです。それが何かを意味するかどうかはわかりませんが、私が見た唯一の奇妙な行動です。誰でも支援を提供できますか?

4

1 に答える 1