Как проверить файл, чтобы убедиться, что он является допустимым файлом XML, прежде чем загружать его с помощью XDocument.Load ()? - PullRequest
33 голосов
/ 17 декабря 2008

Я загружаю XML-документ в свое приложение C # со следующим:

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

но перед этим я делаю тест, чтобы убедиться, что файл существует с:

File.Exists(myfile);

Но ... есть ли (простой) способ проверить файл перед XDocument.Load (), чтобы убедиться, что это действительный файл XML? Другими словами, мой пользователь может случайно щелкнуть другой файл в браузере файлов, и попытка загрузить, скажем, файл .php вызывает исключение.

Единственный способ, которым я могу придумать, - это загрузить его в StreamWriter и просто выполнить текстовый поиск по первым нескольким символам, чтобы убедиться, что они говорят "

Спасибо!

-Adeena

Ответы [ 6 ]

43 голосов
/ 17 декабря 2008

Вероятно, стоит просто поймать конкретное исключение, если вы хотите показать сообщение пользователю:

 try
 {
   XDocument xd1 = new XDocument();
   xd1 = XDocument.Load(myfile);
 }
 catch (XmlException exception)
 {
     ShowMessage("Your XML was probably bad...");
 }
28 голосов
/ 17 декабря 2008

Этот вопрос путает " правильно сформированный " с " допустимым " XML-документом .

Действительный XML-документ по определению является правильно сформированным документом. Дополнительно , он должен удовлетворять DTD или схеме (схема xml , relaxng схема , схематрон или другие ограничения ) должны быть действительными.

Судя по формулировке вопроса, скорее всего, он задает:

«Как убедиться, что файл содержит правильно сформированный документ XML?».

Ответ заключается в том, что документ XML корректно сформирован, если его можно успешно проанализировать с помощью совместимого анализатора XML. Поскольку метод XDocument.Load () делает именно это, вам нужно только перехватить исключение и затем сделать вывод, что текст, содержащийся в файле, сформирован неправильно.

10 голосов
/ 17 декабря 2008

Просто загрузите его и поймайте исключение. То же самое для File.Exists() - файловая система volatile , так что даже если File.Exists() возвращает true, это не означает, что вы сможете открыть ее.

3 голосов
/ 17 декабря 2008

Если у вас есть XSD для XML, попробуйте это:

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

1 голос
/ 09 июля 2017

Я бы не стал XDocument.Load () согласно принятому ответу; зачем читать весь файл в память, это может быть огромный файл?

Я бы, вероятно, прочитал первые несколько байтов в byteArray (это может быть даже любой двоичный файл), преобразовал бы byteArray в строку например System.Text.Encoding.ASCII.GetString(byteArray), проверьте, содержит ли преобразованная строка ожидаемые элементы Xml, только затем продолжите.

1 голос
/ 17 декабря 2008

Как уже упоминалось, "действительный 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... 
        } 
    } 
} 
...