web-dev-qa-db-fra.com

Comment tester un fichier pour voir s'il s'agit d'un fichier XML valide avant de le charger avec XDocument.Load ()?

Je charge un document XML dans mon application C # avec les éléments suivants:

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

mais avant cela, je teste pour m'assurer que le fichier existe avec:

File.Exists(myfile);

Mais ... existe-t-il un moyen (facile) de tester le fichier avant XDocument.Load () pour vous assurer qu'il s'agit d'un fichier XML valide? En d'autres termes, mon utilisateur peut accidentellement cliquer sur un autre fichier dans le navigateur de fichiers et essayer de charger, disons, un fichier .php provoque une exception.

La seule façon dont je peux penser est de le charger dans un StreamWriter et de faire une recherche de texte sur les premiers caractères pour s'assurer qu'ils disent "

Merci!

-Adeena

34
adeena

Cela vaut probablement la peine d'attraper l'exception spécifique si vous souhaitez afficher un message à l'utilisateur:

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

Cette question confond " bien formé " avec " valide " document XML .

Un document xml valide est par définition un document bien formé. De plus , il doit satisfaire un [~ # ~] dtd [~ # ~] ou un schéma (un schéma xml , un schéma relaxng , schematron ou - autres contraintes ) pour être valide.

À en juger par le libellé de la question, elle pose très probablement la question suivante:

"Comment s'assurer qu'un fichier contient un document XML bien formé?".

La réponse est qu'un document XML est bien formé s'il peut être analysé avec succès par un analyseur XML conforme. Comme la méthode XDocument.Load () fait exactement cela, il vous suffit d'attraper l'exception et de conclure que le texte contenu dans le dossier n'est pas bien formé.

28
Dimitre Novatchev

Il suffit de le charger et d'attraper l'exception. Idem pour File.Exists() - le système de fichiers est volatile donc juste parce que File.Exists() retourne vrai ne signifie pas que vous pourrez l'ouvrir.

10
Joel Coehoorn

Si vous avez un XSD pour le XML, essayez ceci:

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

La référence est ici:

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

3
Colby Africa

Comme cela a été mentionné précédemment, "xml valide" est testé par XmlDocument.Load (). Attrapez juste l'exception. Si vous avez besoin d'une validation supplémentaire pour tester sa validité par rapport à un schéma, voici ce que vous recherchez:

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

Je ne voudrais pas XDocument.Load (), selon la réponse acceptée; pourquoi voudriez-vous lire l'intégralité du fichier en mémoire, ce pourrait être un énorme fichier?

J'aurais probablement lu les premiers octets dans un octetArray (il pourrait même s'agir de n'importe quel fichier binaire), convertissez l'octetArray en chaîne, par ex. System.Text.Encoding.ASCII.GetString(byteArray), vérifiez si la chaîne convertie contient les éléments Xml que vous attendez, puis continuez.

0
joedotnot