Utilisation du DOM sous Lazarus/Free Pascal


précédentsommairesuivant

V. Concepts avancés

V-A. La classe TDOMParser

Pour utiliser des concepts plus avancés tels que la validation d'un document XML ou l'utilisation des espaces de noms, nous aurons recours à un objet TDOMParser. Cette classe permet aussi de mettre en œuvre une gestion avancée des erreurs pouvant survenir lors du traitement d'un document XML.

 
Sélectionnez
 TDOMParser = class(TObject)
  private
    {...}
  public
    constructor Create;
    destructor Destroy; override;
    procedure Parse(Src: TXMLInputSource; out ADoc: TXMLDocument);
    procedure ParseUri(const URI: WideString; out ADoc: TXMLDocument);
    function ParseWithContext(Src: TXMLInputSource; Context: TDOMNode; Action: TXMLContextAction): TDOMNode;
    property Options: TDOMParseOptions read FOptions;
    property OnError: TXMLErrorEvent read FOnError write FOnError;
  end;   

Un objet TDOMParser pour être utilisé, doit être l'attribut d'une classe donnée afin de mettre en œuvre la gestion des erreurs.
La propriété onError definit la fonction à appeler quand une erreur survient lors du traitement du document XML. Options définit les paramètres qui vont permettre la validation d'un document XML ainsi que l'utilisation des espaces de noms.

Nous allons construire une classe qui nous permettra de parser et de valider un document XML contenu dans un fichier à l'aide de la classe TDOMParser.

 
Sélectionnez
type myParseur=class
                 private
 
                  error : boolean;
                  errMessage : String;
                  path : string;
                  validate : boolean;
                  ns : boolean;
 
                  procedure onError(Err: EXMLReadError);
 
                 public
 
                  constructor init(pth : String);
                  procedure setValidate(b : boolean);
                  procedure setNameSpace(b: boolean);
                  function doParse(): TXMLDocument;
                  function isError() : boolean;
                  function getErrorMessage() : String;
 
                 end;
 
 constructor myParseur.init(pth : String);
 begin
  self.path:=pth;
  error:=false;
  errMessage:='';
  validate:=false;
  ns:=false;
 end;
 
 procedure myParseur.setValidate(b : boolean);
 begin
  validate:=b;
 end;
 
 procedure myParseur.setNameSpace(b: boolean);
 begin
  ns:=b;
 end;
 
 function  myParseur.doparse() : TXMLDocument;
  var fichier : textFile;
      source : TXMLInputSource;
      sourceFic : TFileStream;
      doc : TXMLDocument;
      parseur : TDOMParser;
 begin
 
 try
  sourceFic:= TFileStream.Create(path, fmOpenRead);
  source:= TXMLInputSource.create(sourceFic);
 
 except
  doParse:=nil;
  error:=true;
  errMessage:='Impossible de lire le fichier '+path;
  exit;
 end ;
 
  doc:=nil;
  parseur:= TDOMParser.Create;
  parseur.OnError:=@onError;
  parseur.Options.Validate:=validate;
  parseur.Options.Namespaces:=ns;
  try
   parseur.Parse(source, doc);
  except
  end;
 
  doParse:=doc;
 end;
 
 function myParseur.isError() : boolean;
 begin
  isError:=error;
 end;
 
 function myParseur.getErrorMessage() : String;
 begin
   getErrorMessage:=errMessage;
 end;
 
  procedure myParseur.onError(Err: EXMLReadError);
  begin
   error:=true;
   errMessage:=err.ErrorMessage;
  end;
 

La méthode onError() est la méthode qui sera appelée dynamiquement par le programme quand une erreur survient lors du traitement du document. Une référence vers cette fonction doit être passée à l'attribut onError de la classe TDOMParser.

 
Sélectionnez
parseur.OnError:=@onError;

Le reste du code peut se passer de tout commentaire puisque je suppose que vous avez déjà acquis les bases de la programmation objet.

V-B. La validation

Vous savez sans doute qu'en XML il n'y a pas de balises prédéfinies. On peut donc définir les balises comme on le souhaite et les placer n'importe où dans un document. Mais pour être sûr qu'un document XML soit compris par une autre application, nous devons définir un protocole de communication qui servira à valider le document XML.

Pour valider un document XML, on peut soit utiliser un DTD (Document Type Definition) ou un document XSD (XML Schema Definition). A ma connaissance, l'API que nous utilisons supporte uniquement l'utilisation de DTD pour la validation d'un document XML.

Pour valider un document XML, nous allons utiliser la classe TDOMParser, mais nous allons modifier le paramètre Options

 
Sélectionnez
  TDOMParseOptions = class(TObject)
  private
    {...}
  public
    property Validate: Boolean read FValidate write FValidate;
    property PreserveWhitespace: Boolean read FPreserveWhitespace write FPreserveWhitespace;
    property ExpandEntities: Boolean read FExpandEntities write FExpandEntities;
    property IgnoreComments: Boolean read FIgnoreComments write FIgnoreComments;
    property CDSectionsAsText: Boolean read FCDSectionsAsText write FCDSectionsAsText;
    property ResolveExternals: Boolean read FResolveExternals write FResolveExternals;
    property Namespaces: Boolean read FNamespaces write FNamespaces;
  end;

Le paramètre qui nous interesse ici est Options.Validate. Sa valeur à true indique qu'on desire valider le document à parser à l'aide d'un DTD. Nous allons parser et valider le document XML suivant :

 
Sélectionnez
<?xml version="1.0" ?>
<!DOCTYPE developpez
  [
  <!ELEMENT developpez (membre*)>
  <!ELEMENT membre (pseudo, message, status)>
  <!ATTLIST membre id ID #REQUIRED>
  <!ELEMENT pseudo (#PCDATA)>
  <!ELEMENT message (#PCDATA)>
  <!ELEMENT status (#PCDATA)>
  ]
>
 <developpez>
  <membre id="n1">
   <pseudo >darrylsite</pseudo>
   <message>500</message>
   <status>redacteur</status>
 </membre>
 <membre id="m2">
   <pseudo>mbr</pseudo>
   <message>1500</message>
   <status>moderateur</status>
 </membre>
</developpez>
  

Voici un exemple qui fait le travail voulu :

 
Sélectionnez
program validation;
 
{$mode objfpc}{$H+}
 
uses dom, xmlRead, xmlWrite, classes;      
 
type myParseur=class
                 {...}
               end;  
 
  var
    parseur : myParseur;
    doc     : TXMLDocument;
 
begin
 
 parseur:= MyParseur.init('test.xml');
 parseur.setValidate(true);//on indique ici qu'on veut valider le xml
 doc:=parseur.doParse();
 if(parseur.isError()) then
  begin
   writeln('Erreur : '+parseur.getErrorMessage())
  end
 else
  writeln('Le document xml est conforme');
 
 readln;
end.
  

En exécutant ce code, vous aurez un message disant que le document est conforme. Mais si on change, par exemple, la première balise membre par membres, une erreur survient avec le message Using undeclared attribute 'id' on element 'membres'.


précédentsommairesuivant

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2010 Darryl Kpizingui. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.