Msxml 4.0 validation xml / xsd

Soyez le premier à donner votre avis sur cette source.

Vue 31 214 fois - Téléchargée 631 fois

Description

Bonjour,

Dans le cadre de mon travail, j'ai été amené à utiliser la librairie Microsoft XML 4.0 au sein de Delphi.

Le but est de permettre la validation d'un document XML grâce à un schéma XSD.
Il fut difficile de trouver de bonnes sources sur ce sujet, je vous partage donc la conclusion de mes recherches.

La source est pour Delphi 6 (réalisé avec Delphi 6 Professionnel) mais devrait fonctionner sur plus récents.

Pour utiliser MSXML, dans Delphi faites :
menu "Projet" \ "importer une bibliothèque de types"
Dans la fenêtre qui s'affiche :
choisir "Microsoft XML, v4.0 (Version 4.0)"
Sélectionner une palette pour ajouter les composants.
Et appuyer sur "creer l'unité" ou "installer".

La partie la plus intéréssante est l'Unité XSDValidator.pas :

Source / Exemple :


unit XSDValidator;

interface

uses
  Classes, MSXML2_TLB;
  
type
  { Pour faciliter la validation voici un
    object regroupant un document XML en DOM
    et une collection de schemas XSD. }
  TXSDValidator = class(TObject)
  private
    _Async: Boolean;
    _XmlDocument: IXMLDOMDocument2;
    _SchemaCollection: IXMLDOMSchemaCollection2;

    ERROR_STR: WideString;
  protected
    function _Get_XMLDOC: IXMLDOMDocument2;
    procedure _Set_XMLDOC(xml: IXMLDOMDocument2);

    function _Get_SCHEMAS: IXMLDOMSchemaCollection2;
    procedure _Set_SCHEMAS(xsds: IXMLDOMSchemaCollection2);

    function _Get_ASYNC: Boolean;
    procedure _Set_ASYNC(value: Boolean);

    function _Get_ERROR: string;

    function GetNameSpaceURI(domdoc: IXMLDOMDocument2): string;
  public
    constructor Create;
    destructor Destroy; override;

    property Async: Boolean read _Get_ASYNC write _Set_ASYNC;
    property XmlDoc: IXMLDOMDocument2 read _Get_XMLDOC write _Set_XMLDOC;
    property Schemas: IXMLDOMSchemaCollection2 read _Get_SCHEMAS write _Set_SCHEMAS;

    property Error: string read _Get_ERROR;

    function AddXsdFile(const filename: string): Boolean;
    function AddXsd(const xsdtxt:WideString): Boolean;
    
    function ParseXmlFile(const filename: string): Boolean;
    function ParseXml(const xmltxt: WideString): Boolean;

    function Valid: Boolean;
  end;

implementation

uses
  Variants, SysUtils, ActiveX, ComObj;

constructor TXSDValidator.Create;
begin
  XmlDoc := CoDOMDocument40.Create();
  XmlDoc.validateOnParse := false;
  Schemas := CoXMLSchemaCache40.Create();
  Async := false;
end;

destructor TXSDValidator.Destroy;
begin
  FreeAndNil(_XmlDocument);
  FreeAndNil(_SchemaCollection);
  inherited;
end;

function TXSDValidator._Get_XMLDOC: IXMLDOMDocument2;
begin
  if not Assigned(_XmlDocument) then
    _XmlDocument := CoDOMDocument40.Create();
    
  result:= _XmlDocument;
end;

procedure TXSDValidator._Set_XMLDOC(xml: IXMLDOMDocument2);
begin
  if Assigned(_XmlDocument) then
    FreeAndNil(_XmlDocument);

  _XmlDocument := xml;
end;

function TXSDValidator._Get_SCHEMAS: IXMLDOMSchemaCollection2;
begin
  if not Assigned(_SchemaCollection) then
    _SchemaCollection := CoXMLSchemaCache40.Create();

  result:= _SchemaCollection;
end;

procedure TXSDValidator._Set_SCHEMAS(xsds: IXMLDOMSchemaCollection2);
begin
  if Assigned(_SchemaCollection) then
    FreeAndNil(_SchemaCollection);
    
  _SchemaCollection := xsds;
end;

function TXSDValidator._Get_ASYNC: Boolean;
begin
  result:= _Async;
end;

procedure TXSDValidator._Set_ASYNC(value: Boolean);
begin
  _Async:= value;
end;

function TXSDValidator._Get_ERROR: string;
begin
  if ERROR_STR <> null then
    result:= ERROR_STR
  else
    result:= '';
end;

function TXSDValidator.GetNameSpaceURI(domdoc: IXMLDOMDocument2): string;
var
  targetNamespaceNode: IXMLDOMNode;
begin
  targetNamespaceNode := domdoc.documentElement.attributes.getNamedItem('targetNamespace');
  
  if Assigned(targetNamespaceNode) then
    result := targetNamespaceNode.nodeValue
  else
    result := '';
end;

function TXSDValidator.Valid: Boolean;
var
  parseError: IXMLDOMParseError;
  Reason: WideString;
begin
  XmlDoc.schemas := Schemas;

  parseError := XmlDoc.validate();
  Reason := parseError.reason;

  if ( Reason <> null ) and ( Reason <> '' ) then
  begin
    ERROR_STR:= Reason;
    result:= false;
  end
  else
    result:= true;
end;

function TXSDValidator.AddXsdFile(const filename: string): Boolean;
var
  XsdDocument: IXMLDOMDocument2;
begin
  XsdDocument := CoDOMDocument40.Create();
  XsdDocument.async := Async;
  
  if XsdDocument.load(filename) then
  begin
    Schemas.Add( GetNameSpaceURI(XsdDocument), XsdDocument);
    result:= true;
  end
  else
  begin
    ERROR_STR:= XsdDocument.parseError.reason;
    result:= false;
  end;
end;

function TXSDValidator.AddXsd(const xsdtxt:WideString): Boolean;
var
  XsdDocument: IXMLDOMDocument2;
begin
  XsdDocument := CoDOMDocument40.Create();
  XsdDocument.async := Async;

  if XsdDocument.loadXML(xsdtxt) then
  begin
    Schemas.Add( GetNameSpaceURI(XsdDocument), XsdDocument);
    result:= true;
  end
  else
  begin
    ERROR_STR:= XsdDocument.parseError.reason;
    result:= false;
  end;
end;

function TXSDValidator.ParseXmlFile(const filename: string): Boolean;
begin
  XmlDoc.async := Async;
  if not XmlDoc.load(filename) then
  begin
    ERROR_STR:= XmlDoc.parseError.reason;
    result:= false;
  end
  else
    result:= true;
end;

function TXSDValidator.ParseXml(const xmltxt: WideString): Boolean;
begin
  XmlDoc.async := Async;
  if not XmlDoc.loadXML(xmltxt) then
  begin
    ERROR_STR:= XmlDoc.parseError.reason;
    result:= false;
  end
  else
    result:= true;
end;

initialization
  if Assigned(ComObj.CoInitializeEx) then
    ComObj.CoInitializeEx(nil, COINIT_MULTITHREADED)
  else
    CoInitialize(nil);
finalization
  CoUninitialize;
end.

Conclusion :


Navré, la source n'est pas commenté mais je pense que c'est assez lisible !

Bonne journée,
RedTux

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1
Date d'inscription
vendredi 10 février 2012
Statut
Membre
Dernière intervention
30 juin 2012

Dear Friend

I run the program and the next error shows
undeclare identifier "IXMLDOMSchemaCollection2"
Messages postés
1
Date d'inscription
mardi 13 avril 2004
Statut
Membre
Dernière intervention
22 février 2011

il est très bien ce code.
En plus c'est sympa de partager car ces fonctionnalités sont peu documentées

merci!
Messages postés
19
Date d'inscription
dimanche 2 novembre 2003
Statut
Membre
Dernière intervention
26 novembre 2013

La raison à l'absence de commentaire est peut-être toute simple : Il ne faut pas être navrer et essayer de commenter la source. Pour quelqu'un qui n'y connait pas grand chose à XML et DOM des explications (voir un Turoriel) sur XML et XSD auraient été les bien venues
Messages postés
12
Date d'inscription
lundi 29 novembre 2004
Statut
Membre
Dernière intervention
14 avril 2010

Bonjour,

Personne n'aurait de commentaire sur mon code ?
Une partie à améliorer, corriger, etc. ?

N'hésitez pas, je ne mords pas !

Cdt,

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Du même auteur (redtux)