简体   繁体   English

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

[英]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:我正在使用以下内容在我的 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?但是......是否有一种(简单的)方法可以在 XDocument.Load() 之前测试文件以确保它是一个有效的 XML 文件? 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.换句话说,我的用户可能会不小心点击文件浏览器中的不同文件并尝试加载,比如说,一个 .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 -阿迪娜

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 .这个问题混淆了“格式良好的”和“有效的”XML 文档

A valid xml document is by definition a well formed document.根据定义,有效的 xml 文档是格式良好的文档。 Additionally , it must satisfy a DTD or a schema (an xml schema , a relaxng schema , schematron or other constraints ) to be valid.此外,它必须满足DTD或模式( xml 模式relaxng 模式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.答案是,如果 XML 文档可以被兼容的 XML 解析器成功解析,那么它就是格式良好的。 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.由于XDocument.Load()方法正是这样做的,因此您只需捕获异常,然后得出文件中包含的文本格式不正确的结论。

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.Exists()也是如此——文件系统是易变的,所以仅仅因为File.Exists()返回 true 并不意味着你将能够打开它。

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

As has previously been mentioned "valid xml" is tested by XmlDocument.Load().正如前面提到的,“有效的 xml”是由 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;根据接受的答案,我不会 XDocument.Load(); 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.我可能会将前几个字节读入 byteArray(它甚至可以是任何二进制文件),将 byteArray 转换为字符串,例如System.Text.Encoding.ASCII.GetString(byteArray) ,检查转换后的字符串是否包含 Xml 元素你在期待,然后才继续。

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.我知道这个线程已经有将近 12 年的历史了,但我仍然想添加我的解决方案,因为我在其他任何地方都找不到它。 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.我认为你想要的只是一种检查文件是否为 xml 文件的方法,而不是文件是否结构良好或其他任何东西。 (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:我找到了一种方法可以轻松检查文件是否为 xml 文件(或您需要的任何文件,这适用于任何情况),这将是以下代码行:

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

Just replace the "filePath" with the path of your file and you're good to go.只需将“filePath”替换为您的文件路径即可。 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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