0

.NET を使用して XSD に対して FilePath で XML ファイルを検証する簡単なクラスを作成しました (以下を参照)。

LAN 上の別のマシンによって生成された大量のデータ ファイルがありますが、ファイルは真の XML ではなく、形式が正しくありませんが、毎回同じように、その構造に基づいて、コンテンツのグローバルな置換を行うことができます。ファイルを修正します。したがって、XSD でテストする前にこれらを修正する必要があります。などと交換<\する必要</があります。すべての置換はコードにリストされています。

これを、約 50k ファイルのリストでファイルを生成するマシンの LAN ネットワーク共有にポイントすると、完了するまでに約 15 分かかりました。これは LAN によって制限された IO にすぎないのか、それともここで行う置換よりも不正な XML を修正するためのより良い (より迅速な) 方法があるのか​​ どうか疑問に思っています。

class VCheck
{
    private static XmlReaderSettings settings = new XmlReaderSettings();
    private bool valid;
    string message;
    public string Message { get { return message; } }

    public VCheck()
    {
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
        settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
        settings.Schemas.Add(null, "schema.xsd");
    }

    public bool CheckFile(string FileFullPath) 
    {
        StreamReader file = new StreamReader(FileFullPath);
        valid = true;
        message = null;
        try
        { //setup xml reader with settings
            XmlReader xml = XmlReader.Create(new StringReader(@"<?xml version='1.0'?><root xmlns=""MYE"">" + 
            file.ReadToEnd().Replace(@"<\", @"</").Replace("&", "&amp;").Replace("\"", "&quot;").Replace("'", "&apos;") + "</root>"), 
            settings);

            while (xml.Read()) ; //read in all xml, validating against xsd
        }
        catch
        {
            //problem reading the xml file in, bad path, disk error etc.
            return false;
        }

        return valid;
    }

    void ValidationCallBack(object sender, ValidationEventArgs e) //called on failed validations
    {
        valid = false;
        message = e.Message;
        switch (e.Severity)
        {
            case XmlSeverityType.Error:
                //Do stuff on validation error
                break;
            case XmlSeverityType.Warning:
                //Do stuff on validation warning
                break;
        }

    }

}

次のようにメインから呼び出します。

    static void Main(string[] args)
    {
        VCheck checker = new VCheck();
        foreach (string file in files) //files is a List<string> of file paths/names
        {
            if (!checker.CheckFile(file))
            {
                //To do stuff if not valid
            }
        }
}
4

2 に答える 2

1

私はそれをすべてメモリに読み込むとは思わない - ReadToEnd- そして、String.Replaceあなたのパフォーマンスの問題に関しては、内容を実行することは良い選択です.

もし私があなたなら、これらのファイルを「1 つずつ」書き直します。つまり、その場でデータをバッファリングして置換します。

新しいファイルを作成し、不正な形式のファイルの一部をバッファー (たとえば 4 kb) にロードし、置換を行い、結果を新しく作成したファイルにフラッシュします。すすぎ、繰り返します。

注意: あるバッファが で終わり<、次のバッファが で始まる場合があり\ます。s (など)を見逃したくない場合は<\、そのような場合も処理する必要があります。

もう1つの可能な解決策は、「より寛容な」独自の実装を試して作成することですXmlReader(このクラスは封印されていないため、それに基づいて独自に作成できます)が、個人的には行っていません。これが良いアプローチかどうかはわかりません。ファイルを書き直すことで、少なくとも構文的に有効な XML を残すことができます。これは、ある時点で役立つ可能性があります。


PS。余談ですが:

    catch
    {
        //problem reading the xml file in, bad path, disk error etc.
        return false;
    }

私はそれをしません。呼び出し元には、操作が失敗した理由がまったくわかりません。

于 2012-08-21T13:51:57.520 に答える
0

最も速いプロセスは、まったく実行する必要がないプロセスです。そこで、「整形式でない XML」の取り扱いに関する Michael Kay のコメントに注目してください。

XML として処理したい非 XML データがマシンによって生成されている場合、そのマシンが現在修正しようとしている非 XML データの代わりに XML データを生成できない理由はありません。さらに悪いことに、データ生成プロセスのエラーに対処するために費やす 1 分ごとの努力は、そのプロセスの責任者に、正しい適切な形式の XML を生成していることを納得させるために費やした 1 分間でもあります。ですから、あなたがここで傷ついているのはあなた自身だけではありません。

于 2012-08-21T17:23:18.953 に答える