Lire un fichier XML sans sa DTD

Lire un fichier XML sans sa DTD - C#/.NET managed - Programmation

Marsh Posté le 09-02-2005 à 13:34:52    

Bonjour à tous,
 
Je rencontre un problème pour lire un fichier XML sans sa DTD.
Ce document se présente ainsi :

Citation :


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE message SYSTEM "mcto-1-0.dtd">
<message>
 <codage>
  <format value="MCTO"/>
  <version value="1.0"/>
 </codage>
 <entete>
  <origine>
   <emetteur>
    <libelle>Tous les tours</libelle>
   </emetteur>
   <date_emission>
    <date_hms>
     <date jour="12" mois="12" annee="2002"/>
     <hms heure="07" minute="04" seconde="04"/>
    </date_hms>
   </date_emission>
   <canal_distribution value="TEL"/>
  </origine>
  <recepteur code="C0012"/>
  <payeur code="444"/>
  <decimales>2</decimales>
  <devise value="EUR"/>
 </entete>
</message


 
Je ne possède pas le fichier mcto-1-0.dtd, mais j'aimerai parcourir le fichier pour récupérer l'attribut "value" du node <format> contenu dans le node <codage> : c'est à dire "MCTO".
 
L'utilisation de la classe XMLDocument n'est pas possible : en effet, lors de l'appel de la méthode Load(string filename), j'ai une exception de levée (le dtd n'a pas été trouvé...).
 
Je me suis tourné vers XmlTextReader, mais là encore je bloque. Lors du parcours de mon fichier avec la méthode Read(), j'ai une exception lorsque le lecteur arrive sur le DOCTYPE (dtd non trouvée) :  

Citation :

while (xmlTextReader.EOF != true)
{
 xmlTextReader.Read();  
}


 
Bref, je ne m'en sors pas :'(
 
Si quelqu'un a une solution je suis preneur :)

Reply

Marsh Posté le 09-02-2005 à 13:34:52   

Reply

Marsh Posté le 09-02-2005 à 14:58:42    

Ben vire la ligne <!DOCTYPE alors...

Reply

Marsh Posté le 09-02-2005 à 18:45:29    

J'aurai du préciser que je ne peux pas modifier le fichier bien sur ! ;)

Reply

Marsh Posté le 09-02-2005 à 18:54:30    

C'est étrange tout cela, la méthode Load de XMLDocument précise ceci :

Citation :

Cette méthode n'effectue aucune validation DTD ou de schéma. Si vous souhaitez qu'une validation ait lieu, vous devez passer un XmlValidatingReader, spécifier le XmlValidatingReader.ValidationType approprié et fournir un XmlValidatingReader.ValidationEventHandler.

Reply

Marsh Posté le 09-02-2005 à 18:59:21    

C'est étrange en effet, il n'y a soit disant pas de validation DTD.  
 
Toutefois, essaie de faire un Load sur le document XML que j'ai donné, tu verras qu'il envois un XMLException en précisant qu'il ne trouve pas le fichier .dtd.

Reply

Marsh Posté le 09-02-2005 à 19:00:11    

Ok, j'vais faire un essai

Reply

Marsh Posté le 09-02-2005 à 19:09:14    

Ok, j'ai trouvé :

Code :
  1. Dim Reader As New Xml.XmlTextReader("taist.xml" )
  2. Reader.XmlResolver = Nothing
  3. Dim XmlDoc As New Xml.XmlDocument
  4. XmlDoc.Load(Reader)


 
En fait, faut utiliser un XmlTextReader, et mettre la propriété XmlResolver à Nothing (null donc en C#). Voici ce que dit la MSDN :

Citation :

XmlResolver à utiliser. Si la valeur est une référence null (Nothing dans Visual Basic), les ressources externes ne sont pas résolues.


 
:)


Message édité par FlorentG le 09-02-2005 à 19:09:37
Reply

Marsh Posté le 09-02-2005 à 19:25:14    

Yes !!! ça marche !
En fait je m'étais orienté vers la propriété ProhibitDtd de XmlTextReader qui ne resolvait pas mon problème. Là ça fonctionne :sol:
 
Merci beaucoup :hello:

Reply

Marsh Posté le 09-02-2005 à 19:25:46    

:jap: :)

Reply

Marsh Posté le 10-02-2005 à 11:11:35    

Je post la solution complète au cas ou cela puisse resservir :

Code :
  1. /// <summary>
  2.  ///  Détermine si un fichier est un fichier de type MCTO.
  3.  /// </summary>
  4.  /// <remarks>Un fichier est de type MCTO si c'est un fichier XML et qu'il est de la forme :
  5.  /// <code>
  6.  /// &lt;codage&gt;
  7.  ///  &lt;format value="MCTO"/&gt;
  8.  /// &lt;/codage&gt;
  9.  /// </code>
  10.  /// </remarks>
  11.  /// <param name="FileName">Chemin d'acces au fichier.</param>
  12.  /// <returns>
  13.  ///  True si le fichier est de type MCTO, faux sinon.
  14.  /// </returns>
  15. private bool IsDocumentMCTO(string FileName)
  16.  {
  17.   bool trouve = false;
  18.   XmlTextReader tr=null;
  19.   try
  20.   {
  21.    tr = new XmlTextReader(FileName);
  22.    tr.XmlResolver = null;
  23.    XmlDocument doc = new XmlDocument();
  24.    doc.Load(tr);
  25.    XmlNodeList list = doc.GetElementsByTagName("codage" );
  26.    foreach (XmlNode node in list)
  27.    {
  28.     if (node.HasChildNodes)
  29.     {
  30.      for (int i=0; i<node.ChildNodes.Count; i++)
  31.      {
  32.       if (node.ChildNodes[i].Name == "format" )
  33.       {
  34.        for (int j=0; j<node.ChildNodes[i].Attributes.Count; j++)
  35.        {
  36.         if (node.ChildNodes[i].Attributes[j].Name == "value" )
  37.         {
  38.          if (node.ChildNodes[i].Attributes[j].Value == "MCTO" )
  39.          {
  40.           trouve = true;
  41.           break;
  42.          }
  43.         }
  44.        }
  45.       }
  46.      }
  47.     }
  48.    }
  49.    tr.Close();
  50.   }
  51.   catch (XmlException e)
  52.   {
  53.   }
  54.   return trouve;
  55.  }

Reply

Marsh Posté le 10-02-2005 à 11:11:35   

Reply

Marsh Posté le 10-02-2005 à 11:12:50    

Par contre, change le catch vide, c'est pas bien de masquer les exceptions ;)

Reply

Marsh Posté le 10-02-2005 à 11:14:28    

C'est une version release là c'est pour ça :D

Reply

Marsh Posté le 10-02-2005 à 11:14:42    

Pas bien quand-même :D

Reply

Marsh Posté le 10-02-2005 à 11:15:26    

Ouais mais y faut pas faire peur au client :o

Reply

Marsh Posté le 10-02-2005 à 11:16:50    

Sauf que là si ça plante, il se passera rien, donc le pauvre client va réessayer 5 fois sans rien comprendre. Hors qu'un petit message genre "Erreur lors de la lecture du fichier XML : vérifier que le fichier est un fichier XML valide" ne peut pas faire de mal ;)

Reply

Marsh Posté le 10-02-2005 à 11:29:42    

Hum oui non mais si tu regardes bien ma méthode retourne un bool.
Si c'est un false, c'est que le doc n'est a priori pas de type MCTO, donc c'est à la suite de l'appel de cette fonction que j'avertie l'utilisateur :)

Reply

Marsh Posté le 10-02-2005 à 11:31:55    

Donc, dans ton catch, tu met :

Code :
  1. catch (XmlException e)
  2. {
  3. trouve = false;
  4. }


Par pur soucis de rigueur, et pour éviter les ambiguité ;)

Reply

Marsh Posté le 11-02-2005 à 15:07:59    

Slt le gars,  
je viens de finir mon appli qui consiste à créer un schema XML en tirant différentes infos de la base de données par un méthode d'encapsulation (un GetSchema appelle une collection de "Tables" qui appelle chaque instance de table==>colonnes==> contraintes...). Apres avoir remonté tous mes éléments déjà formaté en XML, je souhaite juste tout copier dans un fichier XML. Voilà comment faire??
Merci d'avance

Reply

Marsh Posté le 11-02-2005 à 15:12:25    

Y'aurait pas moyen genre en sérialisant le schéma d'un DataSet :??:

Reply

Marsh Posté le 11-02-2005 à 15:22:55    

j'utilise pas de DataSet, je remonte tout dans un string.

Reply

Marsh Posté le 11-02-2005 à 15:23:46    

Alors y'a un constructeur de XmlDocument qui accepte une String en entrée, et après y'a une méthode genre Save qui doit pouvoir le sauvegarder vers un fichier :)

Reply

Marsh Posté le 11-02-2005 à 15:26:03    

je regarde cela now thx

Reply

Marsh Posté le 11-02-2005 à 15:35:32    

erfffffff le MSDN me rend fou loll !!

Reply

Marsh Posté le 11-02-2005 à 15:39:56    

Et pourtant, c'est une des meilleure documentation jamais conçue ;)

Reply

Marsh Posté le 11-02-2005 à 15:46:20    

c'est clair mais lol c'est à cause de cela, il y tro d'infos lol mais je crois que c'est parce que je suis encore au taf et que c'est presque le week-end lol

Reply

Marsh Posté le 30-06-2008 à 09:16:11    

Bonjour,
tout d'abord merci pour le bout de code car il m'a aidé.
Toutefois j'ai un deuxième probleme:
Ce code ci-desous:
static void Main(string[] args)
{
 
            XmlTextReader docxml = null;
 
            docxml = new XmlTextReader("U:\\pki_data\\CTE_Beispiel\\addi\\addi\\addexample.xml" );
            docxml.WhitespaceHandling = WhitespaceHandling.None;
            docxml.XmlResolver = null;
            XmlDocument doc = new XmlDocument();
            doc.Load(docxml);
 
            docxml.Read();
            Console.Write("<" + docxml.Name + " " );
            Console.Write("version: " + docxml.GetAttribute("version" ) + ">\n" );
}
 
me donne ceci sur la console(après exécution):
<version: >
 
On dirais que mes fonctions: docxml.Name et docxml.GetAttribute("version" ) ne sont pas prise en compte.
J'ai essayé avec deburg, et je constate qu'elle sont vide c'est à dire docxml.GetAttribute("version" ) =NULL et l'autre aussi pourquoi? je ne sais.
 
Je serais très ravie si quelqu'un pouvais m'aider.
merci d'avance de me venir en aide.

Reply

Marsh Posté le 30-06-2008 à 13:23:36    

Ca c'est du déterrage de topic!


---------------
Another .Net Blog
Reply

Marsh Posté le 30-06-2008 à 13:32:08    

cela ne maide pas troujours :??:

Reply

Marsh Posté le 30-06-2008 à 14:03:47    

Il ressemble à quoi ton XML?


---------------
Another .Net Blog
Reply

Marsh Posté le 30-06-2008 à 14:07:53    

à ceci:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cteobject SYSTEM "ctexl-1.0.dtd">
<cteobject nextpid="337" pid="p0">
<tree type="root" name="add" pid="p2">
<nodelayout xpos="200" ypos="20" pagepid="p1">
<layoutstyle fgcolor="#000000" fontstyle="plain" fontfamily="Arial" bgcolor="#ffffff" fontsize="10"/>
</nodelayout>
<activetag tagtype="Autolayout" pid="p35">
<AUTOLAYOUT distParent="35" type="1" distY="20" alignment="0.0" fixed="false" distX="20"/>
</activetag>
</tree>
</cteobject>
merci

Reply

Marsh Posté le 30-06-2008 à 14:24:00    

Ce code fonctionne:
 

Code :
  1. static void Main(string[] args)
  2. {
  3.     XmlTextReader docxml = new XmlTextReader("C:\\test.xml" );
  4.     docxml.WhitespaceHandling = WhitespaceHandling.None;
  5.     docxml.XmlResolver = null;
  6.     docxml.Read();
  7.     Console.Write("<" + docxml.Name + " " );
  8.     Console.Write("version: " + docxml.GetAttribute("version" ) + ">\n" );
  9.     Console.ReadKey();
  10. }


Message édité par haazheel le 30-06-2008 à 14:24:18

---------------
Another .Net Blog
Reply

Marsh Posté le 30-06-2008 à 15:29:43    

:bounce: merci beaucoup ca marche
oupi  genial :lol:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed