Utilisation des XML schémas avec 4D (2/2)

Christophe KEROMEN

Cette note est la suite de la note 4D-200508-25-FR qui expliquait comment comprendre et générer un schéma pour accompagner un export XML produit par notre base de données. Cette seconde partie aborde la validation d’une structure XML par rapport au schéma associé. ♪

- Titre : Utilisation des XML schémas avec 4D (2/2)

- Auteur : Christophe KEROMEN

- Parution : 1 septembre 2005

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. Introduction

- II. Donnez-moi de l’oXygen

- L’échantillon manquant

- Génération d’échantillon dans oXygen

- Conversions

- Types de données et services Web

- La fonction publiée

- Types de données en mode RPC

- Types de données en mode message/document

- III. Valider un document associé à un schéma

- Outils en ligne

- IV. Sur Windows

- MSXML

- Exemple de programmation

- Application depuis 4D

- Versions de MSXML

- Exemple de code détectant les versions installées sur le poste

- V. Sur OSX

- À la recherche de l’utilitaire perdu

- Les utilitaires disponibles

- Conversion d’une DTD en schéma de données

- Exploitation dans 4D

- Code d’appel

- Informations retournées sur un document non valide

- VI. Conclusion

I - Introduction

Nous savons depuis la première partie de cette note technique comprendre et générer un schéma pour accompagner un export XML produit par notre base de données. Mais tant que nous ne sommes pas capables de demander la validation d’une structure XML par rapport au schéma associé, nous n’atteignons pas totalement notre objectif.

4D ne proposant pas de commande native pour effectuer cette validation, nous devons nous procurer de l’aide extérieure.

II - Donnez-moi de l’oXygen

Avant de nous lancer dans la validation, abordons un problème qu’un utilitaire externe nous aidera également à résoudre.

L’échantillon manquant

Il arrive fréquemment qu’un partenaire externe (client - fournisseur) nous transmette un schéma de données décrivant des données à émettre ou à recevoir. Interpréter un schéma de données n’est pas aussi aisé que lire une bande dessinée : il manque les images, autrement dit un échantillon de structure XML correspondant au schéma fourni. Nous allons voir que les utilitaires XML spécialisés proposent souvent une fonction de génération de ce type d’échantillon.

Génération d’échantillon dans oXygen

Nous allons prendre l’exemple d’oXygen, utilitaire bon marché, écrit en Java et utilisable sur plusieurs plates formes pour l’achat d’une seule licence, bref un outil recommandable :

http://www.oxygenxml.com/.

Lançons l’application, sélectionnons 'Fichier/Nouveau' puis choisissons 'Document XML '. Le dialogue suivant s’affiche :

Figure 1 : génération d’un échantillon XML depuis un XML schéma

Nous indiquons dans ce dialogue que nous souhaitons générer un nouveau document XML en nous appuyant sur un schéma de données existant. Notons au passage qu’une assistance identique est proposée pour d’autres types de modélisation : DTD, Relax NG, NRL.

Nous indiquons l’URL de notre schéma, puis validons. oXygen affiche le nouveau document correspondant au schéma. Par exemple ici en utilisant le schéma de la table CD réalisé dans la première partie de cette note :

<?xml version="1.0" encoding="UTF-8"?>
<CD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="file:/Users/ckeromen/Altair/
CKTI_Informatique/4D_NT_CK/XML%20schemas/4DXMLschema/CD_root.XSD">

<CD.ID_CD></CD.ID_CD>
<CD.Titre></CD.Titre>
<CD.Interprète></CD.Interprète>
<CD.Genre></CD.Genre>
<CD.Pochette></CD.Pochette>
<CD.Description></CD.Description>
<CD.Prix></CD.Prix>
<CD.Date_saisie></CD.Date_saisie>
<CD.Durée_totale></CD.Durée_totale>
<CD.CD_Double></CD.CD_Double>
</CD>

Une aide appréciable lorsque le schéma n’est accompagné d’aucun exemple !

Conversions

oXygen comme ses homologues (par exemple XMLSpy sur Windows) est également capable de convertir une modélisation vers un autre formalisme, par exemple une DTD vers un schéma de données XML.

Les informations contenues n’étant pas strictement équivalentes, cela ne constituera qu’une aide, un point de départ. Par exemple, lors de la conversion d’un XML Schema vers une DTD, vous perdez toutes les informations relatives aux types de données et aux cardinalités…

Types de données et services Web

Les messages échangés par les services Web véhiculent des données. Les types de ces données sont décrits dans le document XML appelé WSDL qui permet à une application cliente de découvrir le contrat à respecter lors de l’appel d’une fonction.

La fonction publiée

La méthode demo_WS_get_CD attend un nom de CD en entrée et retourne pour l’enregistrement correspondant autant de paramètres de sortie que de champs dans la table [CD]. L’objectif est de regarder comment 4D type les paramètres pour les publier en service Web.

Le code de cette méthode très simple :

C_TEXTE($1)   `titre

DECLARATION SOAP($1;Est un texte ;SOAP entrée ;"titreCD")

CHERCHER([CD];[CD]Titre=$1+"@")

Si (Enregistrements trouves([CD])=1)

C_TEXTE(soap_vt_titre)
soap_vt_titre:=[CD]Titre
DECLARATION SOAP(soap_vt_titre;Est un texte ;SOAP sortie ;"titre")

C_BOOLEEN(soap_vb_siDouble)
soap_vb_siDouble:=[CD]CD_Double
DECLARATION SOAP(soap_vb_siDouble;Est un booléen ;SOAP sortie ;"siCDDouble")

C_DATE(soap_vd_date)
soap_vd_date:=[CD]Date saisie
DECLARATION SOAP(soap_vd_date;Est une date ;SOAP sortie ;"dateSaisie")

C_TEXTE(soap_vt_description)
soap_vt_description:=[CD]Description
DECLARATION SOAP(soap_vt_description;Est un texte ;SOAP sortie ;"description")

C_HEURE(soap_vh_duree)
soap_vh_duree:=[CD]Durée_totale
DECLARATION SOAP(soap_vh_duree;Est une heure ;SOAP sortie ;"duree")

C_TEXTE(soap_vt_genre)
soap_vt_genre:=[CD]Genre
DECLARATION SOAP(soap_vt_genre;Est un texte ;SOAP sortie ;"genre")

C_ENTIER LONG(soap_vl_IDCD)
soap_vl_IDCD:=[CD]ID_CD
DECLARATION SOAP(soap_vl_IDCD;Est un entier long ;SOAP sortie ;"IDCD")

C_TEXTE(soap_vt_interprete)
soap_vt_interprete:=[CD]Interprète
DECLARATION SOAP(soap_vt_interprete;Est un texte ;SOAP sortie ;"interprete")

C_BLOB(soap_vx_pochette)
IMAGE VERS BLOB([CD]Pochette;soap_vx_pochette;"JPEG")
DECLARATION SOAP(soap_vx_pochette;Est un BLOB ;SOAP sortie ;"pochette")

C_REEL(soap_vn_prix)
soap_vn_prix:=[CD]Prix
DECLARATION SOAP(soap_vn_prix;Est un numérique ;SOAP sortie ;"prix")

Fin de si

Types de données en mode RPC

Pour obtenir le WSDL du service Web de la base de démonstration, tapez http://localhost:8080/4DWSDL/ dans un navigateur. Voici la description des paramètres du message de réponse du service Web :

<message name="demo_WS_get_CDResponse">
<part name="titre" type="xsd:string"/>
<part name="siCDDouble" type="xsd:boolean"/>
<part name="dateSaisie" type="xsd:date"/>
<part name="description" type="xsd:string"/>
<part name="duree" type="xsd:time"/>
<part name="genre" type="xsd:string"/>
<part name="IDCD" type="xsd:int"/>
<part name="interprete" type="xsd:string"/>
<part name="pochette" type="xsd:base64Binary"/>
<part name="prix" type="xsd:float"/>
</message>

Les types déclarés par 4D dans le WSDL sont exprimés à l’aide des types unitaires de XML Schema que vous connaissez maintenant. On retrouve la déclaration des espaces de noms dans la déclaration XML du WSDL :

xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

Cela permet à une méthode proxy de savoir désérialiser les données du message pour les convertir depuis l’XML reçu vers les types natifs de l’application. Par exemple, 4D génère le code suivant pour une méthode proxy :

C_TEXTE($1)

C_TEXTE(proxy_ret1)
C_BOOLEEN(proxy_ret2)
C_DATE(proxy_ret3)
C_TEXTE(proxy_ret4)
C_HEURE(proxy_ret5)
C_TEXTE(proxy_ret6)
C_ENTIER LONG(proxy_ret7)
C_TEXTE(proxy_ret8)
C_BLOB(proxy_ret9)
C_REEL(proxy_ret10)

FIXER PARAMETRE WEB SERVICE("titreCD";$1)

APPELER WEB SERVICE("http://localhost:8080/4DSOAP/";"A_WebService#demo_WS_get_CD";
"demo_WS_get_CD";"http://www.4d.com/namespace/default";Web Service dynamique )

Si (OK=1)
LIRE RESULTAT WEB SERVICE(proxy_ret1;"titre")
LIRE RESULTAT WEB SERVICE(proxy_ret2;"siCDDouble")
LIRE RESULTAT WEB SERVICE(proxy_ret3;"dateSaisie")
LIRE RESULTAT WEB SERVICE(proxy_ret4;"description")
LIRE RESULTAT WEB SERVICE(proxy_ret5;"duree")
LIRE RESULTAT WEB SERVICE(proxy_ret6;"genre")
LIRE RESULTAT WEB SERVICE(proxy_ret7;"IDCD")
LIRE RESULTAT WEB SERVICE(proxy_ret8;"interprete")
LIRE RESULTAT WEB SERVICE(proxy_ret9;"pochette")
LIRE RESULTAT WEB SERVICE(proxy_ret10;"prix";*)   ` Libération de la mémoire après retour de la valeur.
Fin de si

Vous pouvez vérifier que les types de départ sont bien restaurés.

Types de données en mode message/document

Dans ce mode, prôné par Microsoft .Net, les messages SOAP véhiculent des structures XML décrites par un schéma.

Pour obtenir le WSDL d’une publication dans le mode « message/document », appelé mode DOC dans la documentation 4D, il suffit de taper http://localhost:8080/4DWSDL/doc dans un navigateur. L’élément <types> fournit alors un schéma de données des types véhiculés dans les messages :

<types>
<schema targetNamespace="http://www.4d.com/namespace/default" elementFormDefault="qualified">
<element name="demo_WS_get_CD">
<complexType>
<sequence>
<element minOccurs="1" maxOccurs="1" name="titreCD" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="demo_WS_get_CDResponse">
<complexType>
<sequence>
<element minOccurs="1" maxOccurs="1" name="titre" type="xsd:string"/>
<element minOccurs="1" maxOccurs="1" name="siCDDouble" type="xsd:boolean"/>
<element minOccurs="1" maxOccurs="1" name="dateSaisie" type="xsd:date"/>
<element minOccurs="1" maxOccurs="1" name="description" type="xsd:string"/>
<element minOccurs="1" maxOccurs="1" name="duree" type="xsd:time"/>
<element minOccurs="1" maxOccurs="1" name="genre" type="xsd:string"/>
<element minOccurs="1" maxOccurs="1" name="IDCD" type="xsd:int"/>
<element minOccurs="1" maxOccurs="1" name="interprete" type="xsd:string"/>
<element minOccurs="1" maxOccurs="1" name="pochette" type="xsd:base64Binary"/>
<element minOccurs="1" maxOccurs="1" name="prix" type="xsd:float"/>
</sequence>
</complexType>
</element>
</schema>
</types>

Vous pouvez constater que dans ce mode, le WSDL contient un véritable schéma de données XSD pour chaque message SOAP. C’est un des avantages mis en avant par les promoteurs de ce mode de fonctionnement des services Web.

III - Valider un document associé à un schéma

Attaquons-nous maintenant à notre problème principal : demander la validation d’une structure XML depuis 4D.

Outils en ligne

Il est possible de trouver sur le Web un certain nombre de sites proposant la validation en ligne de vos documents XML. Quoique cela puisse rendre service à l’occasion, ce n’est pas forcément le moyen le plus simple.

Exemple : http://www.w3.org/2001/03/webdata/xsv

En revanche, nous n’avons pas trouvé de service Web en utilisation libre proposant cette fonction. Si vous débusquez ce Graal, faites-nous signe !

IV - Sur Windows

Si nous démarrons notre quête en environnement Microsoft, la solution est fournie sous forme d’une bibliothèque téléchargeable gratuitement : « Microsoft XML Core Services » mieux connue par son petit nom « MSXML ». Cette dll est en général préinstallée dans le système ou lors de l’installation d’Internet Explorer.

MSXML

On trouve sur le site Web de Microsoft deux téléchargements :

- Microsoft Core XML Services (MSXML), en version 6.0 au moment de cette rédaction ;

- MSXML (Microsoft XML Parser) Software Development Kit (SDK), en version 3.0 SP7 au moment de cette rédaction.

Le premier item est installé par défaut sur les versions récentes de Windows et lors des installations d’Internet Explorer qui y recoure abondamment. Il offre une implémentation des standards de base de XML :

- XML 1.0 (DOM & SAX2 API) ;

- XML Schema (XSD) 1.0 ;

- XPath 1.0 ;

- XSLT 1.0.

Le second fournit des ressources de programmations pour la dll dont une indispensable aide Windows : xmlsdk30.chm.

Exemple de programmation

En consultant cette aide, nous apprenons comment demander la validation d’un document XML en JScript :

var x = new ActiveXObject("MSXML2.DOMDocument.4.0");
x.async = false;
x.validateOnParse = true;
x.load("Adresse_xsd.xml");
if (x.parseError.errorCode != 0)
{
WScript.Echo("errorReason=" + x.parseError.reason);
}
else
WScript.Echo("===NO PARSE ERROR===\n");//+ x.xml

Le seul élément variable dans ce script est constitué par l’URL de chargement du document XML : x.load(« Adresse_xsd.xml »);

Il sera par conséquent facile de générer un script de ce type depuis 4D puis de demander son exécution par l’intermédiaire d’un appel à la commande LANCER PROCESS EXTERNE. Pour plus d’informations sur l’emploi de cette commande de 4D 2004 dans le domaine du scripting, reportez-vous à la Note technique 4D-200412-36-FR « Lancer process externe » par Frank CHANG.

Application depuis 4D

Voici le code de la méthode XSD_validate_MSXML demandant la validation sur Windows :

` ----------------------------------------------------

` Nom utilisateur (OS) : christophe Keromen
` Date et heure : 07/07/05, 11:18:06
` ----------------------------------------------------
` Méthode : XSD_validate_MSXML
` Description
` validation du document XML $1 par exécution d’un script VBS appelant MSXML
`
` Paramètres
` $1:TEXTE:chemin d’accès vers le doc XML
` $0:TEXTE:resultat, si vaut "ok" le doc est valide, contient le texte de l’erreur ` sinon
`
` Version : 3
` le 22/11/05, 08:42:27
` on tient compte de la version de msxml dll
`
` Appel : resultat:=demo_XSD_valide (chemin d’accès vers le doc XML)
` ----------------------------------------------------

C_TEXTE($1;$_vt_docXML)
$_vt_docXML:=Caractere(Guillemets )+$1+Caractere(Guillemets )

C_TEXTE($0)
$0:=""

Si (<>XML_msxml_dll_version#"")

Si (Vrai)   `Ex. de script à générer :
`Dim WshShell
`Set WshShell=CreateObject("WScript.Shell")
`
`
`Dim xmlDoc
`set xmlDoc=CreateObject("Msxml2.DOMDocument.5.0")
`
`xmlDoc.async=false
`xmlDoc.validateOnParse=true
`
`xmlDoc.load"C:\\CK_Bureau\\2004-AtelierTechWebService\\SchemaValidate\\Adresse_xs `d.xml"
`
`Set myErr=xmlDoc.parseError
`If(myErr.errorCode<>0)Then
`WScript.Echo("errorReason="+myErr.reason)
`else
` WScript.Echo("ok")
`End If
Fin de si

Si (Vrai)   `--- Génération du script VBS

C_TEXTE($_vt_pathScript)   `le fichier est volontairement placé hors de dossier temporaire
`pour pouvoir le consulter en debug
$_vt_pathScript:="C:\\msxmlvalidate.vbs"

Si (Tester chemin acces($_vt_pathScript)=Est un document )
SUPPRIMER DOCUMENT($_vt_pathScript)
Fin de si

C_HEURE($_vh_RefDoc)
$_vh_RefDoc:=Creer document($_vt_pathScript;"vbs")

C_TEXTE($_vt_script)

$_vt_script:="Dim WshShell"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="Set WshShell=CreateObject(\"WScript.Shell\")"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="Dim xmlDoc"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

`<modif> christophe Keromen (22/11/2005)
`on tient compte de la version de msxml dll
$_vt_script:="set xmlDoc=CreateObject(\"Msxml2.DOMDocument."+<>XML_msxml_dll_version+".0\")"
+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)
`</modif>

$_vt_script:="xmlDoc.async=false"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="xmlDoc.validateOnParse=true"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="xmlDoc.load"+$_vt_docXML+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="Set myErr=xmlDoc.parseError"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="If(myErr.errorCode<>0)Then"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="WScript.Echo(\"errorReason=\"+myErr.reason)"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="else"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="WScript.Echo(\"ok\")"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

$_vt_script:="End If"+Caractere(Retour chariot )
ENVOYER PAQUET($_vh_RefDoc;$_vt_script)

FERMER DOCUMENT($_vh_RefDoc)
Fin de si

Si (Vrai)   `--- Exécution du script

C_TEXTE($_vt_result)
$_vt_result:=LPE_Play ("cscript //Nologo "+$_vt_pathScript)

$0:=Sous chaine($_vt_result;1;Longueur($_vt_result)-2)   `pour éliminer CRLF
Fin de si

Sinon
ok:=0
$0:="msxml*.dll n’est pas installée sur ce Système !"
Fin de si

Notez que nous préférons utiliser le langage VBScript que JScript pour le script que nous générons depuis 4D. Dans notre exemple ce script est enregistré sous « C:\\msxmlvalidate.vbs » pour des raisons de simplification d’appel et de facilité de débogage.

La routine LPE_Play provient de la Note technique 4D-200412-36-FR et encapsule un appel à LANCER PROCESS EXTERNE en cachant sous windows la fenêtre de l’interpréteur de script grâce à la ligne suivante (à partir de la version 2004.1 de 4D) :

FIXER VARIABLE ENVIRONNEMENT("_4D_OPTION_HIDE_CONSOLE";"true")

Versions de MSXML

Attention, la version de MSXML est dépendante de celle installée sur le poste qui exécute le code VBScript.

Un article de la knowledge base Microsoft décrit ce problème :

http://support.microsoft.com/?scid=kb%3Ben-us%3B305019&x=7&y=7 : INFO: MSXML 4.0 Specific GUIDs and ProgIDs

Pour connaître les versions disponibles dans le système il faut regarder dans

« \Winnt\System32\Msxml#.dll », exemple sur le poste de test :

Installation « side by side » : différentes versions se côtoient

Attention, la dll peut être également installée dans d’autres emplacements, par exemple pour Office qui utilise une version spéciale MSXML5.DLL (MSXML 5.0 for Microsoft Office Applications) dans « C:\Program Files\Fichiers communs\Microsoft Shared\OFFICE11 ».

En testant l’existence de ces dll vous pouvez déterminer la version à utiliser dans votre code.

À noter également que MSXML ne fait pas partie du framework .Net qui propose ses propres classes pour gérer le XML.

Exemple de code détectant les versions installées sur le poste

` ----------------------------------------------------
` Nom utilisateur (OS) : christophe Keromen
` Date et heure : 22/11/05, 08:34:45
` ----------------------------------------------------
` Methode : XML_get_MSXML_version
` Description :
` retourne la version de la dll msxml installée dans le système
`
` Parametres :
` $0:TEXTE:version de la dll
`
` Version : 1
` Appel : version de la dll :=XML_get_MSXML_version
` ----------------------------------------------------

C_TEXTE($0)
$0:=""   `renvoie vide si DLL non installée

Si (ENV_siWindows )

`--- chemin d’accès au système
C_TEXTE($_vt_system)
$_vt_system:=Dossier systeme

C_TEXTE($_vt_nomDLL)   `C:\WINDOWS\system32
$_vt_nomDLL:=$_vt_system+"\\System32\\msxml"

TABLEAU TEXTE($_Tt_version;3)
$_Tt_version{1}:="5"   `"6"
`on évite la version 6 qui retourne à tort une erreur de variation sur les nil
$_Tt_version{2}:="4"
$_Tt_version{3}:="3"

C_ENTIER($i)
Boucle ($i;1;Taille tableau($_Tt_version))

Si (Tester chemin acces($_vt_nomDLL+$_Tt_version{$i}+".dll")=Est un document )
$0:=$_Tt_version{$i}
$i:=Taille tableau($_Tt_version)+1
Fin de si

Fin de boucle

Fin de si

V - Sur OSX

Point de MSXML sur MacOSX, il nous faut chercher des bibliothèques de code complémentaires. Sur cette plateforme, il s’agira la plupart du temps de packages Java.

À la recherche de l’utilitaire perdu

Une bonne adresse pour chercher des outils XML sur Internet se trouve ici : http://xmlsoftware.com/

C’est ainsi que nous trouvons le site http://www.xmlmind.com/xsdvalid.html qui propose des outils d’utilisation libre appelables en ligne de commande, donc depuis 4D via LANCER PROCESS EXTERNE. Il s’agit comme nous l’avions prévu de code Java qui pourrait donc fonctionner également sur Windows.

Les utilitaires disponibles

Trois fonctions sont proposées :

dtdvalid ?options? ?xml_doc … xml_doc?
Vérifie la validité d’une DTD, vérifie la validité d’un document XML par rapport à une DTD ;

xsdvalid ?options? ?xml_doc … xml_doc?
Vérifie la validité d’un schéma XML, vérifie la validité d’un document XML par rapport à un schéma XML ;

dtdtoxsd ?options? in_dtd_file out_xsd_file
Convertit une DTD contenue dans un fichier vers un schéma XML généré dans un fichier.

Conversion d’une DTD en schéma de données

Pour nous mettre en appétit, testons d’abord en ligne de commande la conversion d’une DTD en schéma de données, après tout ça peut toujours servir…

Préalable : vérification de la version de java
[PB-CK:~] ckeromen% java -version
java version « 1.4.2_05 »
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-141.4)
Java HotSpot(TM) Client VM (build 1.4.2-38, mixed mode)

Changement de répertoire
[PB-CK:~] ckeromen% cd /Users/ckeromen/Altair/CKTI_Informatique/4D_NT_CK/NT_Word4D/XML\ schemas/xsdvalid-210

Appel de la conversion de la DTD BookCatalogue.dtd vers le schéma XML BookCatalogue.xsd [PB-CK:NT_Word4D/XML schemas/xsdvalid-210] ckeromen% bin/dtdtoxsd BookCatalogue.dtd BookCatalogue.xsd

Je ne reproduis pas le schéma obtenu ici, mais ça marche !

Exploitation dans 4D

Le code nécessaire pour exploiter ces fonctions dans 4D est extrêmement simple puisqu’il suffit de construire la ligne de commande, puis de demander son exécution par la routine LPE_Play déjà citée dans la partie Windows :

` Methode : XSD_validate_OSX

` Description :
` valider un document XML / à un schéma
` utilise XMLmind Xsdvalid Toolset
` http://www.xmlmind.com/xsdvalid.html
`
` Parametres :
` $0:TEXTE:Résultat
` $1:TEXTE:chemin d’accès au format 4D
` $2:TEXTE:chemin vers le schéma si non interne
` $3:TEXTE:options à passer en ligne de commande
`
` Version : 1
` Appel : resultat:=XSD_validate_OSX(chemin d’accès version 4D)
` ----------------------------------------------------

C_TEXTE($1;$_vt_path_XML)
$_vt_path_XML:=$1

C_TEXTE($2;$_vt_Path_XSD)   `non traité
$_vt_Path_XSD:=$2

C_TEXTE($3;$_vt_options)
$_vt_options:=$3

C_TEXTE($0)

C_TEXTE($_vt_folderBin)   `"Dossier 'xsdvalid-210' "
$_vt_folderBin:=zdoc_get_dossier_Structure +"xsdvalid-210:"

FIXER VARIABLE ENVIRONNEMENT("_4D_OPTION_CURRENT_DIRECTORY";$_vt_folderBin+"bin/")

$_vt_path_XML:=ZDOC_pathClassicTopathOSX ($_vt_path_XML)

C_TEXTE($_vt_command)
$_vt_command:="xsdvalid "
Si ($_vt_options#"")
$_vt_command:=$_vt_command+$_vt_options+" "+$_vt_path_XML
Sinon
$_vt_command:=$_vt_command+$_vt_path_XML
Fin de si

$0:=LPE_Play ($_vt_command)

À noter :

- le chemin d’accès vers le dossier contenant les exécutables « xsdvalid-210 », dans notre exemple il est situé au même niveau que la structure ;

- l’utilisation de la précieuse commande FIXER VARIABLE ENVIRONNEMENT (« _4D_OPTION_CURRENT_DIRECTORY »;$_vt_folderBin+« bin/ ») qui permet de changer le répertoire au sein duquel s’exécutera le script. Attention, cette option n’existe que depuis la version 2004.1.

Exemple de ligne de commande passée à LPE_Play :

xsdvalid -o /Volumes/Proxima/Users/ckeromen/Altair/CKTI_Informatique/4D_NT_CK/XML\
schemas/4DXMLschema/logXSD.txt /Volumes/Proxima/Users/ckeromen/Altair/CKTI_Informatique/4D_NT_CK/XML\
schemas/4DXMLschema/CD_rootBad.XML

Note : outre le premier paramètre indiquant le chemin du fichier de log à générer et le second paramètre indiquant le nom du fichier XML, nous passons l’option “-o« qui précise à xsdvalid d’écrire le résultat de son traitement dans le fichier de log. Tout cela est très bien décrit dans la documentation qui accompagne l’utilitaire. D’autres options sont disponibles afin, par exemple, de préciser un chemin d’accès vers un schéma XML donné (différent de celui associé par défaut).

Code d’appel

Il ne reste plus qu’à appeler cette méthode XSD_validate_OSX :

C_TEXTE($_vt_options)

Si (Majuscule enfoncee)
$_vt_options:="-v"   `verbose -> resultat ds l’appel de la fonction

Sinon   `écrit le résultat ds un fichier
$_vt_options:="-o "+ZDOC_pathClassicTopathOSX (XSD_OSX_get_log_path )
Fin de si

$_vt_result:=XSD_validate_OSX ($_vt_docXML;"";$_vt_options)

Si ($_vt_result="")   `pas d’erreur d’exécution de l’utilitaire
$_vt_result:=XSD_validate_OSX_get_result    `on relit le résultat ds le journal
$_vt_docXML:=zdoc_get_NomCourt ($_vt_docXML)

Si ($_vt_result="")
ALERTE("Document '"+$_vt_docXML+"' valide")
Sinon
ALERTE("Document '"+$_vt_docXML+"'Non valide, résultat ds 'logXSD.txt'\net dans le presse-papiers")
Fin de si
Sinon   `erreur d’exécution de l’utilitaire
ALERTE("Erreur d’exécution : \n"+$_vt_result)
Fin de si

ECRIRE TEXTE DANS PRESSE PAPIERS($_vt_result)

Informations retournées sur un document non valide

Testons maintenant la validation du document 'CD_rootBad.XML' où nous avons remplacé l’élément <CD.Interprète> par <CD.Interprète2>.

Le programme nous signale correctement l’erreur correspondante :

file:/Volumes/Proxima/Users/ckeromen/Altair/CKTI_Informatique/4D_NT_CK/XML%20schemas/4DXMLschema/CD_ro
otBad.XML:E:4:2: the sequence of child elements is incorrect [cvc-complex-type.2.4]

file:/Volumes/Proxima/Users/ckeromen/Altair/CKTI_Informatique/4D_NT_CK/XML%20schemas/4DXMLschema/CD_ro
otBad.XML:E:4:2: element cannot contain element « CD.Interprète2 » [cvc-complex-type]

VI - Conclusion

Voici le terme de notre périple au sein des schémas de données XML. Bien entendu, nous sommes loin d’avoir fait le tour de la question et un ouvrage comme celui d’EricVan Vlist chez O’Reilly vous aidera à approfondir le sujet. Néanmoins, vous disposez maintenant des briques de base pour pouvoir utiliser des schémas de données tant sur Windows que sur OSX.