I. Interface de la base exemple▲
La sélection de l’item de menu « Fichier/démo » nous affiche le dialogue suivant :
Chacun des quatre boutons de la partie supérieure gauche de l’écran appelle un mode de génération différent d’un document XML présentant des données issues de la table [CD] :
· DOM : utilise les nouvelles commandes 4D 2004 d’écriture dans un arbre DOM, puis la sérialisation de cet arbre en fichier texte, (cf. la première partie de cette note technique) ;
· SAX : utilise les nouvelles commandes 4D 2004 d’écriture « SAX » dans un document disque ;
· État rapide : utilise une fonctionnalité des états rapides de 4D 2003 pour générer un état d’après un modèle balisé ;
· Balises Web : utilise la nouvelle commande 4D 2004 TRAITER BALISES HTML pour générer un document XML depuis un modèle comportant des balises semi-dynamiques.
La case à cocher « via SOAP » permet de demander d’exécuter le traitement au travers d’une requête SOAP. Dans le cas contraire, il s’agit d’un appel direct. À noter que la requête peut également s’effectuer au travers d’http (depuis n’importe quel navigateur) en saisissant :
http://serveur:8080/4DACTION/CD_ListeXML/mode
où mode peut prendre les valeurs : DOM-SAX-QR-Web.
La zone de texte centrale affiche les 32 000 premiers caractères du résultat de la génération XML.
Le bouton de droite « Navigateur » affiche le résultat de la génération dans un navigateur, de préférence Internet Explorer qui offre, à la date de cette rédaction, le meilleur rendu.
Méthode CD_ListeXML▲
C’est la méthode centrale protéiforme qui peut être appelée directement, par une requête HTTP ou au travers d’un service Web.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
` Methode : CD_Liste_XML
` Description
` Conversion d’une sélection d’utilisateur en XML et renvoi à un appel direct, HTTP ou SOAP
`cette méthode peut aussi être appelée par
`get "http://serveur:8080/4DACTION/CD_ListeXML/mode"
`ou directement : CD_ListeXML("DOM")
`
` Parametres
`$1:TEXTE:Mode (DOM-SAX-QR-Web)
` ----------------------------------------------------
C_TEXTE
(
$1
)
C_TEXTE
(
$_vt_Mode
)
$_vt_Mode
:=
$1
`---Décodage du paramètre d’entrée
Si
(
Est une requete SOAP)
`en mode dynamique, 4D s’occupe de tout
DECLARATION SOAP(
$1
;
Est un texte
;
SOAP entrée
;
"modeConversionXML"
)
Sinon
C_BOOLEEN
(
$_vb_SiRequeteHTTP
)
Si
(
Sous chaine
(
$_vt_Mode
;
1
;
1
)=
"/"
)
`requête HTTP
$_vt_Mode
:=
Sous chaine
(
$_vt_Mode
;
2
)
`pour enlever le "/", ex. dans "/DOM"
$_vb_SiRequeteHTTP
:=
Vrai
Sinon
`appel direct
$_vb_SiRequeteHTTP
:=
Faux
Fin de si
Fin de si
`--- Constitution de la sélection
LECTURE SEULEMENT
([
CD])
TOUT SELECTIONNER
([
CD])
TRIER
([
CD];[
CD]
Titre;>)
`--- conversion en XML
C_TEXTE
(
$_vt_Methode_CallBack
)
$_vt_Methode_CallBack
:=
""
C_BLOB
(
geneXML_vx_XML)
FIXER TAILLE BLOB
(
geneXML_vx_XML;
0
)
C_TEXTE
(
soap_vt_Return)
soap_vt_Return:=
""
Au cas ou
: (
$_vt_Mode
=
"DOM"
)
soap_vt_Return:=
DOM_ListeEnregistrementsVersXML (->[
CD];
$_vt_Methode_CallBack
;->
geneXML_vx_XML)
: (
$_vt_Mode
=
"SAX"
)
soap_vt_Return:=
SAX_listeEnregistrementsVersXML (->[
CD];
$_vt_Methode_CallBack
;->
geneXML_vx_XML)
: (
$_vt_Mode
=
"QR"
)
soap_vt_Return:=
QR_Executer (
$_vt_ModeleXML
;->
geneXML_vx_XML)
: (
$_vt_Mode
=
"Web"
)
C_TEXTE
(
$_vt_ModeleXML
)
`Nom du modèle semi-dynamique
$_vt_ModeleXML
:=
"CD.xml"
soap_vt_Return:=
XML_traiterModele (
$_vt_ModeleXML
;->
geneXML_vx_XML)
Sinon
soap_vt_Return:=
"<erreur>le mode "
+
$_vt_Mode
+
" n’est pas reconnu </erreur>"
TEXTE VERS BLOB
(
soap_vt_Return;
geneXML_vx_XML;
Texte sans longueur )
Fin de cas
`--- Renvoi du résultat
Si
(
Est une requete SOAP)
DECLARATION SOAP(
soap_vt_Return;
Est un texte
;
SOAP sortie
;
"CD_Liste_XML_texte"
)
DECLARATION SOAP(
geneXML_vx_XML;
Est un BLOB
;
SOAP sortie
;
"CD_Liste_XML_BLOB"
)
`maintenant 4D s’occupe de l’encodage et de l’envoi
Sinon
Si
(
$_vb_SiRequeteHTTP
)
`requête HTTP
`précisons le type MIME "text/xml" pour que le navigateur reconnaisse le XML
ENVOYER BLOB HTML(
geneXML_vx_XML;
"text/xml"
)
Fin de si
Fin de si
$0
:=
soap_vt_Return
II. Approche « SAX »▲
Originellement, le terme SAX (Simple API for XML) désigne une API Java pour relire les flux XML suivant une logique orientée événement.
En version 2004, 4D propose une implémentation de cette API pour le langage 4D ainsi qu’une extension à la génération de documents XML.
Différence entre SAX et DOM▲
Deux différences séparent les deux nouveaux jeux de commandes d’écriture XML : la cible et la granularité :
- les commandes DOM travaillent sur un arbre en mémoire, leur niveau de travail est l’élément ;
- les commandes « SAX » travaillent sur un fichier disque, leur niveau de travail est l’élément ou un autre type de nœud : commentaire, section CDATA, instruction de traitement.
En fonction de cette séparation, vous choisirez la famille qui vous convient le mieux. Pour notre exemple, point n’est besoin d’autre type de nœud que l’élément.
Traitement « SAX »▲
Voici le résultat du traitement « SAX » affiché dans un navigateur, vous pouvez constater qu’il ressemble furieusement à ce que nous obtenions précédemment avec l’approche DOM !
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<root>
<!-- Ex. de generation 'SAX' le 31/09/2004 -->
<CD>
<CD.ID_CD>
5</CD.ID_CD>
<CD.Titre>
4 Stabat mater</CD.Titre>
<CD.Interprete>
Divers</CD.Interprete>
<CD.Genre>
Musique sacrée</CD.Genre>
<CD.Description>
Ce double CD réédité par EMI en 1995 réunit 4 Stabat mater.
Celui de Rossini interprété par l’orchestre Symphonique de Berlin dirigé par Karl Forster.
Il est suivi de l’œuvre de Verdi, Philarmonica Orchestra dirigé par Carlo Maria Guilini.
Sur le deuxième CD, on trouve Francis Poulenc interprété par Régine Crespin.
Cette compilation se termine avec une version moins connue, celle du polonais Karol Szymanowski,
Orchestre Symphonique de la Radio Nationale polonaise par Antoni Wit.</CD.Description>
<CD.Prix>
8</CD.Prix>
<CD.DateStock>
2003-01-01T00:00:00</CD.DateStock>
</CD>
<CD>
<CD.ID_CD>
2</CD.ID_CD>
<CD.Titre>
Master serie 1</CD.Titre>
<CD.Interprete>
Sheller William</CD.Interprete>
<CD.Genre>
Chanson française</CD.Genre>
<CD.Description>
Cette compilation de 1987 ressortie en CD en 1991 par Polygram
regroupe les succès du pianiste-compositeur entre 1975 (Photos souvenirs) et
1984 (Simplement)</CD.Description>
<CD.Prix>
4,9</CD.Prix>
<CD.DateStock>
2003-01-01T00:00:00</CD.DateStock>
</CD>
</root>
Notez cependant l’insertion d’un commentaire juste sous la racine.
Méthode SAX_listeEnregistrementsVersXML▲
Cette méthode générique convertit une sélection d’enregistrements en structure XML. Elle ne diffère principalement de DOM_listeEnregistrementsVersXML que par l’utilisation d’un document disque comme cible plutôt qu’un arbre DOM en mémoire.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
` ----------------------------------------------------
` Methode : SAX_listeEnregistrementsVersXML
` Description
` convertit une liste d’enregistrements en structure XML via écriture SAX
`
` Notes :
`- 4D 2004 (utilise les commandes d’écriture SAX)
`- la sélection doit déjà exister
`- ici on retourne ds un BLOB, attention à la taille du XML généré
`
` Parametres
` Parametres
`$1:POINTEUR:Table
`$2:TEXTE:Methode à appeler en callback pour chaque enregistrement
`$3:POINTEUR:BLOB:structure XML
`$0:TEXTE:structure XML
`
` Version : 1
` Appel : texteXML:=SAX_listeEnregistrementsVersXML(->Table;$_vt_Methode_CallBack;-> BLOB XML)
` ----------------------------------------------------
C_POINTEUR
(
$1
)
C_POINTEUR
(
$_vp_Table
)
$_vp_Table
:=
$1
C_TEXTE
(
$2
)
C_TEXTE
(
$_vt_Methode_CallBack
)
$_vt_Methode_CallBack
:=
$2
C_POINTEUR
(
$3
)
C_TEXTE
(
$0
)
$0
:=
""
`--- Installe une gestion d’erreurs
XML_AppelerSurErreur_set
C_TEXTE
(
$_vt_Last_xml_Error
)
$_vt_Last_xml_Error
:=
""
`--- Enregistre le doc XML sur disque
C_TEXTE
(
$_vt_chemin
)
`stockage sur disque dans un fichier temporaire
$_vt_chemin
:=
Dossier temporaire
+
"SAX_temp.xml"
Si
(
Tester chemin acces
(
$_vt_chemin
)=
Est un document
)
SUPPRIMER DOCUMENT
(
$_vt_chemin
)
Fin de si
C_HEURE
(
$_vh_refDoc
)
$_vh_refDoc
:=
Creer document
(
$_vt_chemin
;
"xml"
)
$_vt_chemin
:=
document
Si
(
ok=
1
)
`--- Écriture des options
C_TEXTE
(
$_vt_Encodage
)
$_vt_Encodage
:=
"UTF-8"
C_BOOLEEN
(
$_vb_SiAutonome
)
$_vb_SiAutonome
:=
Vrai
`avec ou sans DTD externe
C_BOOLEEN
(
$_vb_SiIndentation
)
$_vb_SiIndentation
:=
Vrai
`avec whitespaces ou non de présentation
SAX ECRIRE OPTIONS XML (
$_vh_refDoc
;
$_vt_Encodage
;
$_vb_SiAutonome
;
$_vb_SiIndentation
)
`--- Création du document XML en lui passant la racine nommée arbitrairement "root"
C_TEXTE
(
$_vt_root
)
$_vt_root
:=
"root"
SAX OUVRIR ELEMENT XML
(
$_vh_refDoc
;
$_vt_root
)
SAX AJOUTER COMMENTAIRE XML
(
$_vh_refDoc
;
"Ex. de génération'SAX' le "
+
Chaine
(
Date du jour
;
Spécial forcé ))
`--- Export des enregistrements par parcours de la sélection
C_ENTIER(
$i
)
Boucle
(
$i
;
1
;
Enregistrements trouves
(
$_vp_Table
->))
`--- Création de l’élément complexe contenant les champs de l’enregistrement courant
C_ENTIER(
$_ve_SiEncodingISO
)
$_ve_SiEncodingISO
:=
0
`sans encodage ISO (encodage effectué automatiquement par les commandes SAX)
C_TEXTE
(
$_vt_ElementName
)
`nom de l’élément, on pourrait églt prendre un nom générique, ex.<row>
$_vt_ElementName
:=
XMLw_Replace_Char (
Nom de la table
(
$_vp_Table
);
"tag"
;
$_ve_SiEncodingISO
)
SAX OUVRIR ELEMENT XML
(
$_vh_refDoc
;
$_vt_ElementName
)
`--- Rétro-appel de la méthode convertissant l’enregistrement courant en XML
Si
(
$_vt_Methode_CallBack
#
""
)
C_TEXTE
(
$_vt_callback
)
$_vt_callback
:=
$_vt_Methode_CallBack
+
"("
+
Caractere
(
Guillemets
)+
$_vt_RefElementRecord
+
Caractere
(
Guillemets
)+
")"
EXECUTER(
$_vt_callback
)
Sinon
`Générique de conversion en XML
C_ENTIER(
$_ve_siEncodageIso
)
$_ve_siEncodageIso
:=
Num
(
$_vt_Encodage
=
"ISO-8859-1"
)
`pas d'encodage ISO
SAX_EnregistrementVersXML (
$_vh_refDoc
;
$_vp_Table
;
$_vt_ElementName
;
$_ve_siEncodageIso
)
Fin de si
`referme la balise d’enregistrement
SAX FERMER ELEMENT XML
(
$_vh_refDoc
)
$_vt_Last_xml_Error
:=
XML_AppelerSurErreur_getLastErr
Si
(
$_vt_Last_xml_Error
#
""
)
|
(
ok=
0
)
`une erreur est survenue on arrête
$i
:=
Enregistrements trouves
(
$_vp_Table
->)+
1
Sinon
ENREGISTREMENT SUIVANT
(
$_vp_Table
->)
Fin de si
Fin de boucle
SAX FERMER ELEMENT XML
(
$_vh_refDoc
)
`referme la racine et ts les éléments ouverts
FERMER DOCUMENT
(
$_vh_refDoc
)
`referme le doc XML
`chargement du doc dans un BLOB
C_BLOB
(
$_vx_XML
)
DOCUMENT VERS BLOB
(
$_vt_chemin
;
$_vx_XML
)
Sinon
$_vt_Last_xml_Error
:=
"Impossible de créer le document XML"
Fin de si
`--- Gestion des erreurs, validation et enregistrement
Si
(
$_vt_Last_xml_Error
=
""
)
`pas d’erreur
`--- Le doc est-il bien formé ? (on pourrait aussi le valider/DTD)
$3
->:=
$_vx_XML
C_TEXTE
(
$_vt_XML
)
$_vt_XML
:=
DOM_isXML_correct (
$3
)
Si
(
$_vt_XML
#
""
)
$0
:=
$_vt_XML
`OK
Sinon
FIXER TAILLE BLOB
(
$3
->;
0
)
ALERTE
(
"Doc XML mal formé : l’arbre XML a été copié dans les presse-papiers"
)
Fin de si
Sinon
`une erreur est survenue
ALERTE
(
$_vt_Last_xml_Error
)
Fin de si
DEBUT SELECTION
(
$_vp_Table
->)
`on remet le pointeur en début de sélection
Commentaires
Le document XML s’ouvre et se ferme grâce aux commandes traditionnelles Creer document et FERMER DOCUMENT.
SAX ECRIRE OPTIONS XML : permet de fixer différentes options du document XML : encodage, indentation et de préciser si le document est accompagné ou non d’une DTD.
SAX AJOUTER COMMENTAIRE XML : permet d’ajouter un commentaire dans le document XML.
SAX OUVRIR ELEMENT XML : permet d’ouvrir un nouvel élément XML dont on passe le nom.
SAX FERMER ELEMENT XML : le pendant de la commande précédente, mais attention elle referme le dernier nœud ouvert sans précision de son nom, 4D le gère automatiquement. Il convient dans le cas d’élément complexe de ne l’appeler qu’après avoir rajouté attributs ou enfants.
Routine SAX_EnregistrementVersXML▲
Cette méthode générique convertit un enregistrement en XML par les commandes SAX. Elle ne diffère de la méthode DOM_EnregistrementVersXML que par l’utilisation d’un paramètre désignant le document au lieu de l’arbre DOM en mémoire. Elle ne traite pas non plus les champs binaires.
Les routines suivantes sont utilisées :
xmlw_Si_ChampBinaire : est-ce un champ binaire (non traité) ;
XMLw_Replace_Char : remplace ou supprime un caractère posant problème ;
XMLw_get_fieldValue : retourne le contenu d’un champ en texte pour écriture XML.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
` ----------------------------------------------------
` Methode : SAX_EnregistrementVersXML
` Description
` Convertit de manière générique un enregistrement en XML
`
`Notes :
`- ne traite pas les champs binaires
`
` Parametres
`$1:TEXTE:Ref du document en cours de génération
`$2:POINTEUR:Table
`$3:TEXTE:Nom parent pour préfixer
`$4:ENTIER:1 si encodage ISO à appliquer
` ----------------------------------------------------
` SAX_EnregistrementVersXML ($_vh_RefDoc;$_vp_Table;$_vt_ElementName;$_ve_siEncodageIso)
C_HEURE
(
$1
)
C_HEURE
(
$_vh_refDoc
)
$_vh_refDoc
:=
$1
C_POINTEUR
(
$2
)
C_POINTEUR
(
$_vp_PtTable
)
$_vp_PtTable
:=
$2
C_ENTIER LONG
(
$_vl_TableNo
)
$_vl_TableNo
:=
Table
(
$_vp_PtTable
)
C_TEXTE
(
$_vt_prefixe
)
$_vt_prefixe
:=
""
`pour garantir unicité entre tables
C_ENTIER(
$_ve_siEncodageIso
)
$_ve_siEncodageIso
:=
0
`pas d’encodage ISO
Si
(
Nombre de parametres=
2
)
Sinon
$_vt_prefixe
:=
$3
$_ve_siEncodageIso
:=
$4
Fin de si
C_ENTIER(
$i
)
Boucle
(
$i
;
1
;
Nombre de champs(
$_vl_TableNo
))
C_POINTEUR
(
$_vp_Champ
)
$_vp_Champ
:=
Champ
(
$_vl_TableNo
;
$i
)
Si
(
xmlw_Si_ChampBinaire (
$_vp_Champ
))
`on ne traite pas ds cette version
Sinon
C_TEXTE
(
$_vt_TagName
)
$_vt_TagName
:=
XMLw_Replace_Char (
Nom du champ
(
$_vl_TableNo
;
$i
);
"tag"
;
$_ve_SiEncodingISO
)
Si
(
$_vt_prefixe
#
""
)
$_vt_TagName
:=
$_vt_prefixe
+
"."
+
$_vt_TagName
Fin de si
C_TEXTE
(
$_vt_Value
)
$_vt_Value
:=
XMLw_get_fieldValue (
$_vp_Champ
)
`Ajout d’un champ et de sa valeur
SAX_AJOUTER_ELEMENT_SIMPLE (
$_vh_refDoc
;
$_vt_TagName
;
$_vt_Value
)
Fin de si
Fin de boucle
Routine SAX_AJOUTER_ELEMENT_SIMPLE▲
Cette routine se charge d’ajouter un élément et sa valeur au document en cours de génération. L’élément doit être de type simple, c’est-à-dire ne pas contenir d’attributs ou d’enfants.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
` ----------------------------------------------------
` Methode : SAX_AJOUTER_ELEMENT_SIMPLE
` Description
` Ajoute un élément sa valeur et referme l’élément
`
` Parametres
`$1:HEURE:Ref doc
`$2:TEXTE:Nom de l’élément
`$3:TEXTE:Valeur de l’élément
` ----------------------------------------------------
`SAX_AJOUTER_ELEMENT_SIMPLE ($_vh_refDoc;$_vt_TagName;$_vt_Value)
C_HEURE
(
$1
)
C_HEURE
(
$_vh_refDoc
)
$_vh_refDoc
:=
$1
C_TEXTE
(
$2
)
C_TEXTE
(
$_vt_NomElement
)
$_vt_NomElement
:=
$2
C_TEXTE
(
$3
)
C_TEXTE
(
$_vt_ValeurElement
)
$_vt_ValeurElement
:=
$3
SAX OUVRIR ELEMENT XML
(
$_vh_refDoc
;
$_vt_NomElement
)
SAX AJOUTER VALEUR ELEMENT XML
(
$_vh_refDoc
;
$_vt_ValeurElement
)
SAX FERMER ELEMENT XML
(
$_vh_refDoc
)
Routine DOM_isXML_correct▲
Nous utilisons la méthode DOM_isXML_correct pour vérifier si la structure XML générée est bien formée, les routines d’écriture SAX ou DOM ne s’en chargeant pas. Pour cela, nous chargeons la structure dans le parseur grâce à DOM Analyser variable XML et vérifions qu’aucune erreur n’est signalée. Cette méthode pourrait être enrichie pour valider la structure par rapport à une DTD de référence.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
` ----------------------------------------------------
` Methode : DOM_isXML_correct
` Description
` vérifie que l’XML contenu dans le BLOB $1-> est bien formé
`si oui, renvoie ses 32 000 premiers caractères dans $0
`sinon renvoie une chaîne vide
`
` Parametres
` $0:TEXTE:32 000 premiers caractères de la structure XML
`$1:POINTEUR:BLOB contenant un doc XML
`
` Version : 1
` Appel : texteXML:=DOM_isXML_correct(->BLOB XML)
` ----------------------------------------------------
C_POINTEUR
(
$1
)
C_BLOB
(
$_vx_XML
)
$_vx_XML
:=
$1
->
C_TEXTE
(
$_vt_Ref_XML_Analyse
)
$_vt_Ref_XML_Analyse
:=
DOM Analyser variable XML
(
$_vx_XML
)
`--- Conversion en texte
C_TEXTE
(
$_vt_XML
)
DOM EXPORTER VERS VARIABLE
(
$_vt_Ref_XML_Analyse
;
$_vt_XML
)
`Bug 4D : DOM EXPORTER VERS VARIABLE devrait décoder en Mac Roman
$_vt_XML
:=
ISO vers Mac(
$_vt_XML
)
ECRIRE TEXTE DANS PRESSE PAPIERS(
$_vt_XML
)
Si
(
ok=
1
)
&
(
DOM_ifNoError (
$_vt_Ref_XML_Analyse
))
`Retour des valeurs
$0
:=
$_vt_XML
$3
->:=
$_vx_XML
Sinon
FIXER TAILLE BLOB
(
$3
->;
0
)
$0
:=
""
Fin de si
DOM FERMER XML
(
$_vt_Ref_XML_Analyse
)
`l’arbre analysé
Par balises HTML▲
Quoique cette fonctionnalité ait été un peu sous-employée, le serveur Web de 4D sait servir des documents XML depuis la version 6.5.7. Les balises 4D insérées dans un modèle de document XML permettent très facilement d’obtenir un document XML dynamique, c’est-à-dire dont le contenu est construit par le serveur lors de la requête du client.
Cette fonctionnalité va nous offrir un nouveau moyen de générer du XML.
Description du modèle XML▲
Nous devons commencer par construire notre modèle qui effectuera les déclarations indispensables (déclaration XML, balise racine) et contiendra des balises propriétaires qui déclencheront les appels à 4D.
Soit le modèle de document XML suivant :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Liste de CD -->
<XML_4D>
<!--4DSCRIPT/web_script_allSelect/1-->
<!--4DSCRIPT/web_script_sortByDefault/1-->
<!--4DLOOP [CD]-->
<CD>
<titre>
<!--4DVAR [CD]Titre-->
</titre>
<interprete>
<!--4DVAR [CD]Interprete-->
</interprete>
<genre>
<!--4DVAR [CD]Genre-->
</genre>
<description>
<!--4DVAR [CD]Description-->
</description>
<prix>
<!--4DVAR [CD]Prix-->
</prix>
<dateStock>
<!--4DVAR [CD]Date Stock-->
</dateStock>
</CD>
<!--4DENDLOOP-->
</XML_4D>
Reportez-vous à la documentation, section « Balises HTML 4D » pour une description détaillée des balises utilisées ici :
- 4DSCRIPT nous permet de déclencher l’exécution de code, ici pour constituer la sélection initiale sur la table [CD], puis la trier ;
- 4DLOOP est l’équivalent HTML de Boucle, avec son pendant 4DENDLOOP (Fin de boucle) ;
- 4DVAR insère la valeur d’un champ, d’une variable ou d’une expression 4D, nous l’utilisons ici directement pour attaquer des champs de la structure.
Notez qu’il nous appartient ici de construire correctement l’arborescence de notre modèle afin de générer un document XML bien formé.
Nous enregistrons ce modèle nommé « CD.xml » dans le dossier Web de notre structure.
Validation par une requête http▲
Validons notre modèle en demandant son exécution par une requête directe sur le serveur Web de 4D, publié sur le port 8080.
Saisissons l’URL « http://localhost:8080/CD.xml » dans Internet Explorer ou Mozilla (afin de bénéficier de la présentation intégrée du XML), nous obtenons le document ci-dessous :
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Liste de CD -->
<XML_4D>
<CD>
<titre>
4 Stabat mater</titre>
<interprete>
Divers</interprete>
<genre>
Musique sacrée</genre>
<description>
Ce double CD réédité par EMI en 1995 réunit 4 Stabat mater.
Celui de Rossini interprété par l’orchestre Symphonique de Berlin dirigé par Karl Forster.
Il est suivi de l’œuvre de Verdi, Philarmonica Orchestra dirigé par Carlo Maria Guilini.
Sur le deuxième CD, on trouve Francis Poulenc interprété par Régine Crespin.
Cette compilation se termine avec une version moins connue, celle du polonais Karol Szymanowski,
Orchestre Symphonique de la Radio Nationale polonaise par Antoni Wit.</description>
<prix>
8</prix>
<dateStock>
1/01/03</dateStock>
</CD>
<CD>
<titre>
Master serie 1</titre>
<interprete>
Sheller William</interprete>
<genre>
Chanson française</genre>
<description>
Cette compilation de 1987 ressortie en CD en 1991 par Polygram
regroupe les succès du pianiste-compositeur entre 1975 (Photos souvenirs) et
1984 (Simplement)</description>
<prix>
4,9</prix>
<dateStock>
1/01/03</dateStock>
</CD>
4D a automatiquement traité notre modèle et remplacé les balises par les données demandées. Le client Web n’a alors aucun moyen de savoir que le document est issu d’un modèle dynamique.
Notez que dans l’élément <description> du premier CD « l’œuvre » n’est pas correctement encodé. En effet, « œ » ne fait pas partie de l’encodage ISO-8859-1.
Traiter balises HTML▲
Nouveauté de 4D 2004, la commande TRAITER BALISES HTML va nous permettre d’obtenir le même résultat sans passer par une requête Web et donc sans devoir activer le serveur Web !
Extrait de la documentation :
Cette commande permet d’effectuer un traitement sur du code HTML balisé sans qu’il soit nécessaire que le serveur Web envoie une page HTML via une commande du type ENVOYER BLOB HTML ou qu’une page suffixée “.shtml” soit demandée via une URL. Il n’est même pas nécessaire que le serveur Web de 4e Dimension soit démarré.
Paramètres |
Type |
Description |
---|---|---|
données Entrée |
Texte ou BLOB |
Données contenant des balises HTML à traiter |
données Sortie |
Texte ou BLOB |
Données traitées |
Voici le code de l’appel dans la base exemple :
2.
3.
4.
C_TEXTE
(
$_vt_ModeleXML
)
`Nom du modèle semi-dynamique
$_vt_ModeleXML
:=
"CD.xml"
`$0 : contient un message d’erreur ou les 32 000 premiers caractères
$0
:=
XML_traiterModele (
$_vt_ModeleXML
;->
geneXML_vx_XML)
avec la méthode XML_traiterModele :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
` ----------------------------------------------------
` Methode : XML_TraiterModele
` Description
` Traite un modèle dynamique XML $1 pour générer un document statique
` le document doit se trouver dans le dossier 'Dossierweb'
` ATTENTION : utilise la commande 4D 2004 'TRAITER BALISES HTML'
`
` Parametres
` $1:TEXTE:Nom du modèle
` $2:POINTEUR:BLOB de retour
`
` Version : 1
` Appel : texteXML:=XML_TraiterModele(ModeleXML;->BLOBxml)
` ----------------------------------------------------
C_TEXTE
(
$1
)
C_TEXTE
(
$_vt_ModeleXML
)
$_vt_ModeleXML
:=
$1
C_POINTEUR
(
$2
)
C_POINTEUR
(
$_vp_PtBlobRetour
)
$_vp_PtBlobRetour
:=
$2
C_TEXTE
(
$_vt_chemin
)
`chemin d’accès complet au modèle localisé dans DossierWeb
$_vt_chemin
:=
zdoc_get_DossierWeb +
$_vt_ModeleXML
Si
(
Tester chemin acces
(
$_vt_chemin
)=
Est un document
)
`--- Chargement du modèle dans un BLOB
C_BLOB
(
$_vx_ModeleXML
)
DOCUMENT VERS BLOB
(
$_vt_chemin
;
$_vx_ModeleXML
)
`--- traitement des balises 4D et récupération du document traité dans $_vp_PtBlobRetour->
TRAITER BALISES HTML(
$_vx_ModeleXML
;
$_vp_PtBlobRetour
->)
`renvoi des 32 000 premiers caractères dans $0
$0
:=
BLOB vers texte
(
$_vp_PtBlobRetour
->;
Texte sans longueur )
Sinon
$0
:=
"<erreur>Impossible de localiser le modèle XML</erreur>"
Fin de si
Routines utilisées▲
L’exemple utilise un certain nombre de routines utilitaires. Reportez-vous à la base exemple si vous désirez connaître le détail de leur code.
Ci-dessous leur fonction :
XML_Blob_vers_Browser : affichage d’une structure XML dans un navigateur ;
ENV_siWindows : exécution sous Windows ?
ZDOC_OuvrirDocument : ouverture d’un document ;
zdoc_get_DossierWeb : retourne le chemin d’accès au dossier Web proche de la structure ;
zdoc_get_separateur : retourne le séparateur de chemin en fonction de la plateforme ;
zdoc_get_dossier_Structure : retourne le chemin vers le dossier de la structure ;
zdoc_get_DossierParent : retourne le dossier parent d’un document dont on passe le chemin d’accès complet.
Obtenir les références à la base de données▲
Vous pouvez constater que la construction du modèle ci-dessus impose de connaître :
- le vocabulaire des balises (4DLOOP, 4DSCRIPT, 4DVAR,…) ;
- les éléments à référencer (n° de la table, du champ de tri, nom des champs…).
Le plugin gratuit 4D Object Link permet d’exporter dans un fichier texte les différentes références de la base de données que nous désirons publier :
Voici le contenu de l’export pour notre exemple, dans l’ordre, table, champs, méthodes :
4DObjectLinkDocument
GeneXML
1
[CD]
8
Date Stock
Description
Genre
ID_CD
Interprète
Pochette
Prix
Titre
3
web_script_allSelect
web_script_getField
web_script_sortByDefault
0
Ces références sont ensuite récupérables dans les deux principaux éditeurs Web du marché : DreamWeaver et Adobe GoLive.
Voici ce que cela donne une fois importé dans Dreamweaver MX :
Notes
Le plugin 4D Object Link n’est pas carbonisé. Une alternative consiste à utiliser le plugin commercial AutoDoc.
Pour activer les outils de l’onglet 4D, il faut tromper Dreamweaver en changeant l’extension du document : xml -> html.
Bibliographie▲
Outre la documentation de 4e Dimension, vous pouvez vous référer aux notes techniques suivantes :
· 4D-200406-16-FR - « Profiter de la puissance des balises 4D pour afficher vos données sur le Web » ;
· 4D-200111-35-FR - « 4D Web Enchères ».
Par état rapide▲
Le processus ressemble fort à celui décrit dans le paragraphe précédent et se fonde également sur un modèle décrivant le document XML à l’aide de balises propriétaires.
Le modèle▲
Nous utilisons un modèle d’état rapide « QR_modele_XML.xml » stocké dans le dossier « QR_Modeles » présent à côté de la structure de notre démo :
<?xml version="1.0" encoding="ISO-8859-1"?>
<XML_4D>
<!--#4DQRRow-->
<CD>
<!--#4DQRCol;1-->
<titre>
<!--#4DQRData-->
</titre>
<!--/#4DQRCol;1-->
<!--#4DQRCol;2-->
<interprete>
<!--#4DQRData-->
</interprete>
<!--/#4DQRCol;2-->
<!--#4DQRCol;3-->
<genre>
<!--#4DQRData-->
</genre>
<!--/#4DQRCol;3-->
<!--#4DQRCol;4-->
<description>
<!--#4DQRData-->
</description>
<!--/#4DQRCol;4-->
<!--#4DQRCol;5-->
<prix>
<!--#4DQRData-->
</prix>
<!--/#4DQRCol;5-->
<!--#4DQRCol;6-->
<dateStock>
<!--#4DQRData-->
</dateStock>
<!--/#4DQRCol;6-->
</CD>
<!--/#4DQRRow-->
</XML_4D>
Le modèle se charge de déclarer et de structurer le document XML :
· la balise <!--#4DQRRow--> introduit chaque enregistrement [CD] ;
· la balise <!--#4DQRCol;i--> introduit la colonne i ;
· la balise <!--#4DQRData--> insère le contenu de la colonne i, ici chaque colonne prend sa valeur depuis un champ de la table.
Résultat▲
Le document XML généré est identique à celui du paragraphe précédent avec la même limitation sur le codage ISO-Latin-1 et la non-prise en compte du œ.
Code d’exécution (méthode QR_Executer)▲
L’appel de la génération :
2.
3.
4.
5.
C_TEXTE
(
$_vt_ModeleXML
)
`Nom du modèle semi-dynamique
$_vt_ModeleXML
:=
"QR_modele_XML.xml"
`$0 : contient un message d’erreur ou les 32 000 premiers caractères
$0
:=
QR_Executer (
$_vt_ModeleXML
;->
geneXML_vx_XML)
La méthode QR_Executer :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
` ----------------------------------------------------
` Methode : QR_Executer
` Description
` génère un document XML pour la table CD en utilisant un modèle d’état rapide
`
` Parametres
` $1:TEXTE:Nom du modèle
`$2:POINTEUR:BLOB de retour
`$0:TEXTE: contient un message d’erreur ou les 32 000 premiers caractères
`
` Version : 1
` Appel : texteXML:=QR_Executer ($_vt_ModeleXML;->geneXML_vx_XML)
` ----------------------------------------------------
C_TEXTE
(
$1
)
C_TEXTE
(
$_vt_ModeleXML_path
)
`nom du modèle XML
$_vt_ModeleXML_path
:=
$1
C_POINTEUR
(
$2
)
C_POINTEUR
(
$_vp_PtBlob
)
$_vp_PtBlob
:=
$2
C_TEXTE
(
$_vt_ModeleXML_content
)
`Contenu en texte du modèle XML
$_vt_ModeleXML_content
:=
QR_getModele (
$_vt_ModeleXML_path
)
C_TEXTE
(
$_vt_DocXML_Path
)
`chemin d’accès au document XML généré
$_vt_DocXML_Path
:=
zdoc_get_dossier_Structure +
"QR_Modeles"
+
zdoc_get_separateur
$_vt_DocXML_Path
:=
$_vt_DocXML_Path
+
"QR_CD.xml"
Si
(
$_vt_ModeleXML_content
#
""
)
C_ENTIER LONG
(
$_vl_zone
)
$_vl_zone
:=
QR Creer zone hors ecran
QR FIXER TYPE ETAT
(
$_vl_zone
;
QR ETAT
en liste )
QR FIXER TABLE ETAT
(
$_vl_zone
;
Table
(->[
CD]))
TOUT SELECTIONNER
([
CD])
REDUIRE SELECTION
([
CD];
20
)
TRIER
([
CD];[
CD]
Titre;>)
`--- Description des colonnes de l’état
QR INSERER COLONNE
(
$_vl_zone
;
1
;->[
CD]
Titre)
QR INSERER COLONNE
(
$_vl_zone
;
2
;->[
CD]
Interprète)
QR INSERER COLONNE
(
$_vl_zone
;
3
;->[
CD]
Genre)
QR INSERER COLONNE
(
$_vl_zone
;
4
;->[
CD]
Description)
QR INSERER COLONNE
(
$_vl_zone
;
5
;->[
CD]
Prix)
QR INSERER COLONNE
(
$_vl_zone
;
6
;->[
CD]
Date
Stock)
`type de fichier à générer et chemin
QR FIXER DESTINATION
(
$_vl_zone
;
qr fichier HTML
;
$_vt_DocXML_Path
)
`
`Indication du modèle à utiliser
QR FIXER MODELE HTML
(
$_vl_zone
;
$_vt_ModeleXML_content
)
QR EXECUTER
(
$_vl_zone
)
QR SUPPRIMER ZONE HORS ECRAN
(
$_vl_zone
)
Si
(
Tester chemin acces
(
$_vt_DocXML_Path
)=
Est un document
)
`retour du document XML ds le pointeur de BLOB
DOCUMENT VERS BLOB
(
$_vt_DocXML_Path
;
$_vp_PtBlob
->)
$0
:=
BLOB vers texte
(
$_vp_PtBlob
->;
Texte sans longueur )
Sinon
$0
:=
"<erreur>problème dans la génération du document XML</erreur>"
Fin de si
Sinon
$0
:=
"<erreur>Le modèle XML est vide</erreur>"
Fin de si
L’ensemble de cette méthode effectue une génération classique d’état rapide dans une zone hors écran. Les deux commandes notables sont :
- QR FIXER DESTINATION qui indique au moteur de construire un document de type HTML et le chemin d’accès vers ce document ;
- QR FIXER MODELE HTML qui passe au moteur d’état rapide le contenu du modèle à utiliser, attention il s’agit bien du contenu lui-même et non d’un chemin d’accès.
La méthode QR_getModele permet de charger le modèle dans une variable texte, type de paramètre attendu par la commande QR FIXER MODELE HTML :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
` ----------------------------------------------------
` Methode : QR_getModele
` Description
` relit le contenu d’un modèle d’état rapide
` suppose un dossier QR_Modeles près de la structure
`
` Parametres
` $0:TEXTE:contenu du modèle
` $1:TEXTE:nom du modèle
`
` Version : 1
` Appel : contenuModele:=QR_FixerModele(nomModele)
` ----------------------------------------------------
C_TEXTE
(
$1
)
C_TEXTE
(
$_vt_ModeleXML_path
)
`chemin d’accès au modèle XML
$_vt_ModeleXML_path
:=
zdoc_get_dossier_Structure +
"QR_Modeles"
+
zdoc_get_separateur +
$1
C_TEXTE
(
$0
)
$0
:=
""
C_TEXTE
(
$_vt_ModeleXML_content
)
Si
(
Tester chemin acces
(
$_vt_ModeleXML_path
)=
Est un document
)
$_vh_Ref
:=
Ouvrir document
(
$_vt_ModeleXML_path
;
""
;
Mode lecture
)
Si
(
$_vh_Ref
#
†00
:00
:00
†)
RECEVOIR PAQUET
(
$_vh_Ref
;
$_vt_ModeleXML_content
;
32000
)
FERMER DOCUMENT
(
$_vh_Ref
)
Si
(
$_vt_ModeleXML_content
#
""
)
$0
:=
$_vt_ModeleXML_content
Sinon
ALERTE
(
"Le modèle est vide"
)
Fin de si
Fin de si
Sinon
ALERTE
(
"Le modèle '"
+
$_vt_ModeleXML_path
+
"' est introuvable !"
)
Fin de si
Les fonctions des différentes routines utilitaires sont décrites dans le paragraphe précédent.
Bibliographie▲
· La documentation sur les états rapides.
· 4D-200310-29-FR Etats rapides : les différents types de sorties.
III. Conclusion▲
Vous pouvez constater qu’en version 2004 les moyens ne manquent pas pour générer des documents XML à partir de vos données 4D.
Deux familles se distinguent :
- DOM et SAX offrant une vue XML et un traitement complet par commande ;
- l’approche orientée « modèle dynamique » représentée par les balises Web et les états rapides.
Notez que la première famille, apparue avec 4D 2004, offre l’intérêt de permettre un encodage du XML en UTF-8, bien meilleure option que la lacunaire conversion en ISO-8859-1. Lors d’un traitement en ligne (requête HTTP ou SOAP), l’approche DOM qui travaille en mémoire sera plus rapide que celle par « SAX » qui impose un passage par disque.
Nous espérons vous avoir donné avec cette note les informations nécessaires pour que vous puissiez effectuer votre choix en fonction des circonstances.
IV. Base exemple▲
Téléchargez la base exemple.