web-dev-qa-db-ja.com

XDocument.Load()でロードする前に、ファイルをテストして有効なXMLファイルかどうかを確認するにはどうすればよいですか?

次のようにして、C#アプリケーションにXMLドキュメントをロードしています。

XDocument xd1 = new XDocument();
xd1 = XDocument.Load(myfile);

しかしその前に、ファイルが次のように存在することを確認するためにテストを行います。

File.Exists(myfile);

しかし... XDocument.Load()の前にファイルをテストして有効なXMLファイルであることを確認する(簡単な)方法はありますか?つまり、ユーザーが誤ってファイルブラウザーで別のファイルをクリックして、.phpファイルを読み込もうとすると例外が発生します。

私が考えることができる唯一の方法は、それをStreamWriterにロードして、最初の数文字を単純にテキスト検索して、「

ありがとう!

-アディエナ

34
adeena

ユーザーにメッセージを表示したい場合は、特定の例外をキャッチするだけの価値があります。

 try
 {
   XDocument xd1 = new XDocument();
   xd1 = XDocument.Load(myfile);
 }
 catch (XmlException exception)
 {
     ShowMessage("Your XML was probably bad...");
 }
43
Jennifer

この質問は、「 整形式 」と「 有効 "XMLドキュメントを混同します。

有効なxmlドキュメントは、定義上、整形式のドキュメントです。 さらに、それは [〜#〜] dtd [〜#〜] またはaスキーマ(an xml schema 、a relaxng schema 、- schematron または other constraint )を有効にします。

質問の文言から判断すると、おそらくそれは尋ねます:

"ファイルに整形式のXMLドキュメントが含まれていることを確認する方法は?"

答えは、準拠したXMLパーサーによってXMLドキュメントを正常に解析できれば、XMLドキュメントは整形式であるということです。 XDocument.Load() メソッドはこれを正確に実行するので、例外をキャッチして、ファイルに含まれるテキストがよく形成された。

28

ロードして例外をキャッチするだけです。 File.Exists()の場合も同じです。ファイルシステムはvolatileなので、File.Exists()がtrueを返すからといって、ファイルを開くことができるわけではありません。

10
Joel Coehoorn

XMLのXSDがある場合は、次のことを試してください。

using System;
using System.Xml;
using System.Xml.Schema;
using System.IO;
public class ValidXSD 
{
    public static void Main()
    {
        // Set the validation settings.
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
        settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

        // Create the XmlReader object.
        XmlReader reader = XmlReader.Create("inlineSchema.xml", settings);

        // Parse the file. 
        while (reader.Read());
    }

    // Display any warnings or errors.
    private static void ValidationCallBack (object sender, ValidationEventArgs args) 
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.WriteLine("\tWarning: Matching schema not found.  No validation occurred." + args.Message);
        else
            Console.WriteLine("\tValidation error: " + args.Message);
    }  
}

参照はここにあります:

http://msdn.Microsoft.com/en-us/library/system.xml.xmlreadersettings.validationeventhandler.aspx

3
Colby Africa

前述のように、「有効なxml」はXmlDocument.Load()によってテストされます。例外をキャッチしてください。スキーマに対して有効であることをテストするためにさらに検証が必要な場合、これはあなたがしていることを行います:

using System.Xml; 
using System.Xml.Schema; 
using System.IO; 

static class Program
{     
    private static bool _Valid = true; //Until we find otherwise 

    private static void Invalidated() 
    { 
        _Valid = false; 
    } 

    private static bool Validated(XmlTextReader Xml, XmlTextReader Xsd) 
    { 

        var MySchema = XmlSchema.Read(Xsd, new ValidationEventHandler(Invalidated)); 

        var MySettings = new XmlReaderSettings(); 
        { 
            MySettings.IgnoreComments = true; 
            MySettings.IgnoreProcessingInstructions = true; 
            MySettings.IgnoreWhitespace = true; 
        } 

        var MyXml = XmlReader.Create(Xml, MySettings); 
        while (MyXml.Read) { 
          //Parsing...
        } 
        return _Valid; 
    } 

    public static void Main() 
    { 
        var XsdPath = "C:\\Path\\To\\MySchemaDocument.xsd"; 
        var XmlPath = "C:\\Path\\To\\MyXmlDocument.xml"; 

        var XsdDoc = new XmlTextReader(XsdPath); 
        var XmlDoc = new XmlTextReader(XmlPath); 

        var WellFormed = true; 

        XmlDocument xDoc = new XmlDocument(); 
        try { 
            xDoc.Load(XmlDoc); 
        } 
        catch (XmlException Ex) { 
            WellFormed = false; 
        } 

        if (WellFormed & Validated(XmlDoc, XsdDoc)) { 
          //Do stuff with my well formed and validated XmlDocument instance... 
        } 
    } 
} 
1
BenAlabaster

受け入れられた回答に従って、XDocument.Load()はしません。ファイル全体をメモリに読み込むのはなぜですか。巨大なファイルになる可能性があります。

私はおそらく最初の数バイトをbyteArray(バイナリファイルでさえあり得る)に読み込み、byteArrayを文字列に変換します。 System.Text.Encoding.ASCII.GetString(byteArray)、変換された文字列に予期したXml要素が含まれているかどうかを確認してから、続行してください。

0
joedotnot