如何在使用XDocument.Load()加载文件之前测试一个文件,看看它是否是一个有效的XML文件?

时间:2022-12-09 16:03:34

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

我在我的c#应用程序中加载了一个XML文档:

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.

但是…在XDocument.Load()之前,是否有一种(简单的)方法来测试这个文件,以确保它是一个有效的XML文件?换句话说,我的用户可能不小心单击了文件浏览器中的另一个文件,并试图加载一个.php文件导致异常。

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 "

我能想到的唯一的方法是将它加载到StreamWriter中然后简单地对前几个字符进行文本搜索以确保它们说

Thanks!

谢谢!

-Adeena

-Adeena

6 个解决方案

#1


41  

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

#2


26  

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

这个问题混淆了“格式良好”和“有效”的XML文档。

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.

根据定义,有效的xml文档是格式良好的文档。此外,它必须满足DTD或模式(xml模式、弛豫模式、schematron或其他约束)是有效的。

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

从问题的措辞来看,它很可能会问:

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

“如何确保文件包含格式良好的XML文档?”

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.

答案是,如果可以通过兼容的XML解析器成功解析XML文档,那么XML文档就是格式良好的。正如XDocument.Load()方法所做的那样,您只需要捕获异常,然后得出文件中包含的文本格式不太好。

#3


9  

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.

只需加载它并捕获异常。对于file . exist()也一样——文件系统是不稳定的,所以仅仅因为file . exist()返回true并不意味着您可以打开它。

#4


3  

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

如果您有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);
    }  
}

Reference is here:

参考这里:

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

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

#5


1  

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:

正如前面提到的,“有效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... 
        } 
    } 
} 

#6


1  

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?

我不会按照所接受的答案来装载XDocument.Load();为什么要把整个文件读入内存,它可能是一个巨大的文件?

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

我可能会将前几个字节读入byteArray(甚至可以是任何二进制文件),将byteArray转换为string,例如System.Text.Encoding.ASCII.GetString(byteArray),检查转换后的字符串是否包含预期的Xml元素,然后继续。

#1


41  

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

#2


26  

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

这个问题混淆了“格式良好”和“有效”的XML文档。

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.

根据定义,有效的xml文档是格式良好的文档。此外,它必须满足DTD或模式(xml模式、弛豫模式、schematron或其他约束)是有效的。

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

从问题的措辞来看,它很可能会问:

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

“如何确保文件包含格式良好的XML文档?”

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.

答案是,如果可以通过兼容的XML解析器成功解析XML文档,那么XML文档就是格式良好的。正如XDocument.Load()方法所做的那样,您只需要捕获异常,然后得出文件中包含的文本格式不太好。

#3


9  

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.

只需加载它并捕获异常。对于file . exist()也一样——文件系统是不稳定的,所以仅仅因为file . exist()返回true并不意味着您可以打开它。

#4


3  

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

如果您有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);
    }  
}

Reference is here:

参考这里:

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

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

#5


1  

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:

正如前面提到的,“有效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... 
        } 
    } 
} 

#6


1  

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?

我不会按照所接受的答案来装载XDocument.Load();为什么要把整个文件读入内存,它可能是一个巨大的文件?

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

我可能会将前几个字节读入byteArray(甚至可以是任何二进制文件),将byteArray转换为string,例如System.Text.Encoding.ASCII.GetString(byteArray),检查转换后的字符串是否包含预期的Xml元素,然后继续。