简体   繁体   中英

How does one test a file to see if it's a valid XML file before loading it with XDocument.Load()?

I'm loading an XML document in my C# application with the following:

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

but before that, I do test to make sure the file exists with:

File.Exists(myfile);

But... is there an (easy) way to test the file before the XDocument.Load() to make sure it's a valid XML file? In other words, my user can accidentally click on a different file in the file browser and trying to load, say, a .php file causes an exception.

The only way I can think of is to load it into a StreamWriter and simple do a text search on the first few characters to make sure they say "

Thanks!

-Adeena

It's probably just worth catching the specific exception if you want to show a message to the user:

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

This question confuses " well-formed " with " valid " XML document .

A valid xml document is by definition a well formed document. Additionally , it must satisfy a DTD or a schema (an xml schema , a relaxng schema , schematron or other constraints ) to be valid.

Judging from the wording of the question, most probably it asks:

"How to make sure a file contains a well-formed XML document?".

The answer is that an XML document is well-formed if it can be parsed successfully by a compliant XML parser. As the XDocument.Load() method does exactly this, you only need to catch the exception and then conclude that the text contained in the file is not well formed.

Just load it and catch the exception. Same for File.Exists() - the file system is volatile so just because File.Exists() returns true doesn't mean you'll be able to open it.

If you have an XSD for the XML, try this:

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);
    }  
}

Reference is here:

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

As has previously been mentioned "valid xml" is tested by XmlDocument.Load(). Just catch the exception. If you need further validation to test that it's valid against a schema, then this does what you're after:

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... 
        } 
    } 
} 

I would not XDocument.Load(), as per the accepted answer; why would you read the entire file into memory, it could be a huge file?

I'd probably read the first few bytes into a byteArray (it could even be any binary file), convert the byteArray to string eg System.Text.Encoding.ASCII.GetString(byteArray) ,check if the converted string contains the Xml elements you are expecting, only then continue.

I know this thread is almost 12 years old but I still would like to add my solution as I can't find it anywhere else. What I think you want is just a way to check if the file is a xml File, not if the file is well structured or anything. (that's how I understand the question).

I found a way to easily check if a file is a xml file (or whatever file you need, this works for anything) and that would be the following line of code:

new System.IO.FileInfo(filePath).Extension == ".xml"

Just replace the "filePath" with the path of your file and you're good to go. You can put the statement wherever a boolean is expected.

You can use it like this:

boolean isXmlFile = new FileInfo("c:\\config.xml").Extension == ".xml" //will return true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM