I. Approche DOM▲
Gestion de l’arbre DOM▲
Tout se passe en mémoire et le processus commence par la création d’un arbre DOM. Cela s’effectue en passant le nom de l’élément racine à la commande DOM Creer ref XML qui en échange nous renvoie une référence (alpha 16) sur l’élément créé.
La commande DOM ECRIRE OPTIONS XML permet de fixer certaines options de la structure XML.
Encodage
Ce paramètre se passe sous la forme d’une chaîne de caractère spécifiant un encodage (UTF-8, UTF-16, ISO-8859-1…). La liste des valeurs possibles se retrouve dans la liste déroulante « encodage » dans l’onglet XML du dialogue d’export en utilisation directe. Ce paramètre se retrouvera dans l’attribut encoding de la déclaration XML du document.
Ex. : en passant la valeur UTF-8, on obtiendra la déclaration :
<?xml version="1.0" encoding="UTF-8" ?>
La portée de ce paramètre ne se limite pas à fixer l’attribut de la déclaration XML, il s’agit d’une option active que 4D utilisera pour encoder automatiquement toutes les valeurs qui lui seront passées.
Autonome
Ce paramètre permet de préciser si la structure XML se réfère ou non à une DTD externe, sa valeur se retrouvera dans l’attribut standalone de la déclaration XML du document.
Ex. : en passant Vrai, on obtiendra la déclaration suivante :
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
Indentation
Ce paramètre passé à Vrai entraîne une mise en forme de l’arbre XML à l’aide d’espaces et de retours chariot :
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<valeursXML>
<Champ1>
<value1>
liste1_choix1 </value>
<value1>
liste1_choix3 </value>
<value1>
liste1_choix2 </value>
</Champ1>
<Champ2>
<value1>
liste2_choix2 </value>
<value1>
liste2_choix4 </value>
</Champ2>
<Champ3>
<value1>
liste3_choix2 </value>
</Champ3>
</valeursXML>
Passé à Faux, la structure se présente de la manière suivante :
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<valeursXML><Champ1><value1>
liste1_choix1</value><value1>
liste1_choix3 </value><value1>
liste1_choix2</value></Champ1><Champ2><value1>
liste2_choix2</value><value1>
liste2_choix4</
value></Champ2><Champ3><value1>
liste3_choix2</value></Champ3></valeursXML>
Certains parseurs XML n’apprécient que très moyennement les espaces blancs (whitespaces) de mise en forme. Il est donc important de pouvoir maîtriser ce paramètre. Contrairement aux deux premiers paramètres, la valeur passée ne se retrouve pas sous forme d’attributs dans le document XML cible.
DOM EXPORTER VERS VARIABLE permet de convertir l’arbre en mémoire en variable texte ou BLOB (opération de sérialisation). Son pendant pour écrire l’arbre dans un document est DOM EXPORTER VERS FICHIER. Notez que cette commande ne vérifie pas que votre document est bien formé ni valide. Si vous souhaitez le faire, il faut utiliser la commande DOM Analyser variable XML ou DOM Analyser source XML.
Une fois l’arbre construit et sérialisé dans une variable ou un document disque, il faut penser à le supprimer de la mémoire par l’instruction DOM FERMER XML.
Remplissage de l’arbre▲
Maintenant que nous avons vu comment créer l’arbre, le sérialiser et le libérer de la mémoire, il serait intéressant de savoir comment le remplir !
Pour cela une première série de commandes travaille sur les éléments :
· DOM Creer element XML ;
· DOM ECRIRE VALEUR ELEMENT XML ;
· DOM ECRIRE NOM ELEMENT XML ;
· DOM SUPPRIMER ELEMENT XML.
Tandis qu’une dernière commande s’intéresse aux attributs :
DOM ECRIRE ATTRIBUT XML.
4D se charge automatiquement :
· de l’encodage des valeurs passées ;
· de refermer les éléments :
La commande
$_vt_RefElement
:=
DOM Creer element XML
(
$_vt_RefParent
;
"toto"
)
produit en réalité directement <toto></toto>.
La commande
DOM ECRIRE VALEUR ELEMENT XML
(
$_vt_RefElement
;
"maValeur"
)
se charge ensuite d’insérer la valeur de l’élément pour obtenir : <toto>maValeur</toto>.
Note
Dans la version 2004, les noms des commandes de construction et de parcours d’un arbre DOM ont été renommés pour plus de cohérence avec les commandes d’écriture. Toutes sont désormais préfixées par DOM, ainsi Analyser source XML devient DOM Analyser source XML.
II. Modification de l’enregistrement d’une structure XML▲
Méthode XMLvalues_Record_Save▲
L’enregistrement d’une structure XML s’effectuait dans la section « save » de notre méthode xmlvalues_Record . Pour mieux isoler nos modifications, nous allons créer une méthode XMLvalues_Record_Save qui sera appelée à partir de cette section. Cette méthode sera chargée de convertir les champs de notre interface de saisie de valeurs en XML via l’approche DOM.
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.
` ----------------------------------------------------
` Nom utilisateur (OS) : Christophe Keromen
` Date et heure : 13/05/04, 22:05:04
` ----------------------------------------------------
` Methode : XMLvalues_Record_Save
` Description
` Conversion des champs en XML
`
` Parametres
`$0:TEXTE:structure XML à enregistrer
` ----------------------------------------------------
C_TEXTE
(
$0
)
C_TEXTE
(
$_s_XML
)
$_s_XML
:=
""
`la structure XML à construire
`--- Création de l’arbre DOM et de l’élément racine
C_TEXTE
(
$_s_root
)
$_s_root
:=
"valeursXML"
C_TEXTE
(
$_vt_Ref_DOM_XML
)
$_vt_Ref_DOM_XML
:=
DOM Creer ref XML
(
$_s_root
)
`--- Déclaration XML
C_TEXTE
(
$_vt_Encoding
)
$_vt_Encoding
:=
"UTF-8"
C_BOOLEEN
(
$_vb_StandAlone
)
$_vb_StandAlone
:=
Vrai
C_BOOLEEN
(
$_vb_siIndentation
)
$_vb_siIndentation
:=
Vrai
`indentation pour la facilité de lecture de la structure
DOM ECRIRE OPTIONS XML (
$_vt_Ref_DOM_XML
;
$_vt_Encoding
;
$_vb_StandAlone
;
$_vb_siIndentation
)
$_s_radical
:=
"xmlvalues_S_value"
Boucle
(
$i
;
1
;
Taille tableau
(
xmlvalues_T_fields))
`pour chaque champ de concaténation
$_Pt
:=
Point
eur vers(
$_s_radical
+
Chaine
(
$i
))
Si
(
Non
(
Nil(
$_Pt
)))
` transforme une liste de valeurs
`en série d’éléments XML <value> fils de l’élément passé
XMLvalues_Values2XML_2004 (
$_vt_Ref_DOM_XML
;
xmlvalues_T_fields{$i
};
$_Pt
)
Fin de si
Fin de boucle
`--- Sérialisons notre arbre DOM dans une variable de type texte
DOM EXPORTER VERS VARIABLE
(
$_vt_Ref_DOM_XML
;
$_s_XML
)
$0
:=
$_s_XML
`libération de la mémoire
DOM FERMER XML
(
$_vt_Ref_DOM_XML
)
Méthode XMLvalues_Values2XML_2004▲
La méthode XMLvalues_Record_Save appelle pour chaque champ XMLvalues_Values2XML_2004 qui se charge de convertir la liste des valeurs choisies en structure 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.
`----------------------------------------------------
`Nom utilisateur (OS) : CK
`Date et heure : 13-5-2004
`----------------------------------------------------
`Méthode : XMLvalues_Values2XML_2004
`Description
`transforme une liste de valeurs $3
`en série d’éléments XML <value> fils de l’élément $2
`Paramètres
`$1:TEXTE:Ref de l’arbre DOM
`$2:TEXTE:nom de l’élément père
`$3:POINTEUR:liste de valeurs à transformer
`----------------------------------------------------
C_TEXTE
(
$1
)
C_TEXTE
(
$2
)
C_POINTEUR
(
$3
)
C_TEXTE
(
$_vt_Ref_DOM_XML
)
$_vt_Ref_DOM_XML
:=
$1
C_TEXTE
(
$_s_FieldElement
;
$_s_ChildElement
)
$_s_FieldElement
:=
$2
$_s_ChildElement
:=
"value"
C_POINTEUR
(
$_Pt_valeurs
)
$_Pt_valeurs
:=
$3
Si
(
Non
(
Nil(
$_Pt_valeurs
)))
Si
(
$_Pt_valeurs
->#
""
)
`--- Ouverture de l’élément <Champ{indice}>
C_TEXTE
(
$_vt_RefElement
)
$_vt_RefElement
:=
DOM Creer element XML
(
$_vt_Ref_DOM_XML
;
$_s_FieldElement
)
`--- Transformation de la liste de valeurs séparées par des CR en tableau
TABLEAU TEXTE
(
xmlvalues_T_temp;
0
)
`variable globale "locale"
zgen_TexteVersTableau (
$_Pt_valeurs
->;->
xmlvalues_T_temp;
Caractere
(
Retour chariot
))
`--- Parcours du tableau et transformation de chaque ligne en élément
Boucle
(
$i
;
1
;
Taille tableau
(
xmlvalues_T_temp))
`ouverture de l’élément enfant <value>
C_TEXTE
(
$_vt_RefValue
)
$_vt_RefValue
:=
DOM Creer element XML
(
$_vt_RefElement
;
$_s_ChildElement
)
`écriture de la valeur de l’élément <value>
$_s_value
:=
xmlvalues_T_temp{$i
}
DOM ECRIRE VALEUR ELEMENT XML
(
$_vt_RefValue
;
$_s_value
)
Fin de boucle
TABLEAU TEXTE
(
xmlvalues_T_temp;
0
)
Fin de si
Fin de si
III. Génération d’un document XML pour une sélection d’enregistrements▲
Maintenant que nous maîtrisons l’exécution des commandes DOM dans un cadre particulier, nous allons réaliser une routine qui aura pour objectif de convertir une sélection d’enregistrements en XML de manière générique. Dans cette première note technique, nous utiliserons les commandes DOM et nous verrons dans une seconde partie trois autres moyens de parvenir à nos fins.
Appel depuis l’extérieur▲
Ce genre de routines sera très utile pour la publication de données vers des clients non 4D : formulaires dynamiques, clients SOAP…
Notre code est donc conçu de façon à ce qu’il puisse être appelé :
· depuis un client HTML par un simple 4DACTION ;
· depuis un client SOAP.
Présentation de l’exemple▲
Nous appliquerons ces routines à une structure volontairement très simple comprenant une seule table :
Notre dialogue d’interface, accessible par le menu Fichier/démo, nous permettra d’appeler les différents modes de génération et de visualiser le résultat présenté dans une zone texte :
Notez qu’en version 2004, les zones de texte sont désormais pourvues d’un ascenseur horizontal.
Traitement par DOM▲
Nous allons parcourir la sélection, et pour chaque enregistrement, parcourir l’ensemble des champs de la table et
les convertir en XML. Nous ne traitons pas les éléments binaires pour lesquels XML ne propose pas aujourd’hui
de solution simple et efficace.
Voici notre pseudocode :
DOM_ListeEnregistrementsVersXML : parcourt une sélection d’enregistrements et retourne une structure XML :
<root>
<nom_table>
structure de l’enregistrement</nom_table>
<nom_table>
structure de l’enregistrement</nom_table>
... (autant de fois que d’enregistrements dans la sélection)
</root>
Pour chaque enregistrement DOM_EnregistrementVersXML : convertit chaque champ en un élément
<nom_du_champ>
valeur du champ</nom_du_champ>
Pour chaque champ DOM_set_ElementWithValue : écrit un élément avec sa valeur
Et le résultat dans Internet Explorer (nous retrouvons ici l’un des points forts de XML, si le document s’ouvre dans le navigateur c’est qu’il est bien formé, c’est-à-dire qu’il répond aux règles syntaxiques XML) :
Notez l’adresse d’appel : http://localhost:8080/4DACTION/CD_ListeXML/DOM.
Ce qui signifie envoyer une requête Web (http://) au serveur Web sur la même machine (localhost ou 127.0.0.1) sur le port 8080, appeler le point d’entrée 4DACTION/CD_ListeXML/DOM. 4DACTION étant une URL particulière pour le serveur Web de 4D, celui-ci traduit la requête en « appeler la méthode CD_ListeXML en lui passant le paramètre /DOM ».
Méthode CD_ListeXML▲
Voici le code de la méthode CD_ListeXML
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.
` ----------------------------------------------------
` Nom utilisateur (OS) : Christophe Keromen
` Date et heure : 16/07/04, 09:55:08
` ----------------------------------------------------
` Methode : CD_Liste_XML
` Description
` Conversion d’une sélection d’utilisateur en XML et renvoie à un appel HTTP ou SOAP
` cette méthode peut aussi être appelée par get "http://serveur:8080/4DACTION/CD_Liste_XML/mode"
`
` 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
`requête HTTP
$_vt_Mode
:=
Sous chaine
(
$_vt_Mode
;
2
)
`pour enlever le "/", ex. dans "/DOM"
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
(
soap_vx_Return)
FIXER TAILLE BLOB
(
soap_vx_Return;
0
)
C_TEXTE
(
soap_vt_Return)
soap_vt_Return:=
""
Au cas ou
: (
$_vt_Mode
=
"DOM"
)
soap_vt_Return:=
DOM_ListeEnregistrementsVersXML (->[
CD];
$_vt_Methode_CallBack
;->
soap_vx_Return)
: (
$_vt_Mode
=
"SAX"
)
soap_vt_Return:=
SAX_ListeEnregistrementsVersXML (->[
CD];
$_vt_Methode_CallBack
;->
soap_vx_Return)
: (
$_vt_Mode
=
"QR"
)
soap_vt_Return:=
QR_ListeEnregistrementsVersXML (->[
CD];
$_vt_Methode_CallBack
;->
soap_vx_Return)
: (
$_vt_Mode
=
"Web"
)
soap_vt_Return:=
Web_ListeEnregistrementsVersXML (->[
CD]
;
$_vt_Methode_CallBack
;->
soap_vx_Return)
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(
soap_vx_Return ;
Est un BLOB
;
SOAP sortie
;
"CD_Liste_XML_BLOB"
)
`maintenant 4D s’occupe de l’encodage et de l’envoi
Sinon
`requête http
`précisons le type MIME "text/xml" pour que le navigateur reconnaisse le XML
ENVOYER BLOB HTML(
soap_vx_Return ;
"text/xml"
)
Fin de si
Commentaires
Remarquez la gestion des paramètres d’entrée-sortie suivant l’origine de l’appel, client SOAP ou requête http.
Avec SOAP, les paramètres sont nommés, décrits dans le WSDL et tout assistant du type de celui de 4D permet de générer facilement le code d’appel dit méthode proxy :
En revanche, dans le cas d’une requête http, il n’existe aucun moyen de savoir quelle URL appeler et quel paramètre passer et suivant quelle syntaxe. D’un strict point de vue de consommation de ressources, la requête http reste cependant plus performante.
Méthode DOM_Liste_EnregistrementsVersXML▲
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.
133.
134.
135.
136.
137.
138.
139.
140.
141.
` ----------------------------------------------------
` Nom utilisateur (OS) : christophe Keromen
` Date et heure : 30/06/04, 23:02:34
` ----------------------------------------------------
` Methode : DOM_ListeEnregistrementsVersXML
` Description
` convertit une liste d’enregistrements en structure XML via écriture DOM
`
` Notes :
`- 4D 2004 (utilise les commandes d’écriture DOM)
`- la sélection doit déjà exister
`- ici on retourne ds un BLOB, attention à la taille du XML généré
`
` Parametres
`$1:POINTEUR:Table
`$2:TEXTE:Methode à appeler en callback pour chaque enregistrement
`$3:POINTEUR:BLOB:structure XML
`$0:TEXTE:structure 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
:=
""
XML_AppelerSurErreur_set `Installe une gestion d’erreurs
C_TEXTE
(
$_vt_Last_xml_Error
)
$_vt_Last_xml_Error
:=
""
`--- Création du document XML en lui passant la racine nommée arbitrairement "root"
C_TEXTE
(
$_vt_root
)
$_vt_root
:=
"root"
C_TEXTE
(
$_vt_Ref_XML
)
$_vt_Ref_XML
:=
DOM Creer ref XML
(
$_vt_root
)
`--- Ecriture des options
C_TEXTE
(
$_vt_Encodage
)
$_vt_Encodage
:=
"UTF-8"
`$_vt_Encodage:="ISO-8859-1"
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
DOM ECRIRE OPTIONS XML(
$_vt_Ref_XML
;
$_vt_Encodage
;
$_vb_SiAutonome
;
$_vb_SiIndentation
)
`--- 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 DOM)
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
)
C_TEXTE
(
$_vt_RefElementRecord
)
$_vt_RefElementRecord
:=
DOM Creer element XML
(
$_vt_Ref_XML
;
$_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
:=
0
`pas d’encodage ISO
DOM_EnregistrementVersXML (
$_vt_RefElementRecord
;
$_vp_Table
;
$_vt_ElementName
;
$_ve_siEncodageIso
)
Fin de si
$_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
`--- 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)
C_BLOB
(
$_vx_XML
)
DOM EXPORTER VERS VARIABLE
(
$_vt_Ref_XML
;
$_vx_XML
)
C_TEXTE
(
$_vt_Ref_XML_Analyse
)
$_vt_Ref_XML_Analyse
:=
DOM Analyser variable XML
(
$_vx_XML
)
`--- Conversion en texte
DOM EXPORTER VERS VARIABLE
(
$_vt_Ref_XML
;
$_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
)
ALERTE
(
"Doc XML mal formé : l’arbre XML a été copié dans les presse-papiers"
)
Fin de si
DOM FERMER XML
(
$_vt_Ref_XML_Analyse
)
`l’arbre analysé
Sinon
`une erreur est survenue
ALERTE
(
$_vt_Last_xml_Error
)
Fin de si
DOM FERMER XML
(
$_vt_Ref_XML
)
`l’arbre DOM généré
DEBUT SELECTION
(
$_vp_Table
->)
`on remet le pointeur en début de sélection
Commentaires
Il est possible de passer un paramètre $2
désignant une méthode qui se chargera de convertir l’enregistrement courant en XML au lieu de la méthode générique DOM_EnregistrementVersXML. La routine XML_AppelerSurErreur_set appelle une simple gestion d’erreurs, la dernière erreur rencontrée peut être retrouvée en appelant la méthode accesseur XML_AppelerSurErreur_getLastErr.
DOM creer element XML se charge d’encoder les valeurs passées en accord avec l’option fixée dans DOM ECRIRE OPTIONS XML. Cependant, cela ne comprend pas la vérification des règles syntaxiques XML par exemple l’interdiction d’espace dans les noms d’éléments. C’est pourquoi nous traitons au préalable le nom de l’élément par la routine XMLw_Replace_Char déjà présentée dans la note technique 4D-200402-04- FR.
Une fois toute notre sélection d’enregistrements parcourue, nous utilisons la commande DOM EXPORTER VERS VARIABLE pour récupérer notre arbre DOM dans un BLOB que nous repassons immédiatement à DOM Analyser variable XML afin de vérifier si notre document est bien formé. Si tel est le cas, nous renvoyons à la méthode appelante la structure XML en BLOB et la structure XML convertie en texte. Cette dernière conversion souffre d’un bug de 4e Dimension dans la version à la date de rédaction.
En effet, DOM EXPORTER VERS VARIABLE
(
$_vt_Ref_XML
;
$_vt_XML
)
devrait décoder notre arbre XML encodé en UTF-8 pour, d’après la documentation, nous le ranger dans une variable texte en codage Mac Roman. Le décodage n’est pourtant pas effectué. C’est pourquoi nous conseillons en attendant la correction de ce bug et pour récupérer une version texte, de passer plutôt par un encodage en ISO-8859-1 puis de décoder manuellement (ISO vers Mac) la version texte de la structure XML.
Conversion des champs de l’enregistrement, DOM_EnregistrementVersXML▲
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.
` ----------------------------------------------------
` Nom utilisateur (OS) : christophe Keromen
` Date et heure : 15/07/04, 09:35:02
` ----------------------------------------------------
` Methode : DOM_EnregistrementVersXML
` Description
` Convertit de manière générique un enregistrement en XML
`
` Notes :
` - ne traite pas les champs binaires
`
` Parametres
` $1:TEXTE:Ref de l’élément parent
` $2:POINTEUR:Table
` $3:TEXTE:Nom parent pour préfixer
` $4:ENTIER:1 si encodage ISO à appliquer
` ----------------------------------------------------
` DOM_EnregistrementVersXML ($_vt_RefElementRecord;$_vp_Table;$_vt_ElementName;
` $_ ve_siEncodageIso)
C_TEXTE
(
$1
)
C_TEXTE
(
$_vt_RefElement
)
$_vt_RefElement
:=
$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_ENTIER(
$_vl_TypeChamp
)
LIRE PROPRIETES CHAMP
(
$_vp_Champ
;
$_vl_TypeChamp
)
C_TEXTE
(
$_vt_Value
)
$_vt_Value
:=
""
Au cas ou
: ((
$_vl_TypeChamp
=
Est un champ alpha
)
|
(
$_vl_TypeChamp
=
Est un texte
))
$_vt_Value
:=
$_vp_Champ
->
: ((
$_vl_TypeChamp
=
Est un numérique
)
|
(
$_vl_TypeChamp
=
Est un entier
)
|
(
$_vl_TypeChamp
=
Est un entier long
))
$_vt_Value
:=
Chaine
(
$_vp_Champ
->)
: ((
$_vl_TypeChamp
=
Est une date
))
$_vt_Value
:=
Chaine
(
$_vp_Champ
->;
8
)
`date Time
: ((
$_vl_TypeChamp
=
Est une heure
))
$_vt_Value
:=
Chaine
(
$_vp_Champ
->;
h mn s
)
: ((
$_vl_TypeChamp
=
Est un booléen
))
$_vt_Value
:=
Chaine
(
Num
(
$_vp_Champ
->))
: (
$_vl_TypeChamp
=
Est un BLOB
)
`conversion base64 ?
`-> il faut utiliser BASh, ça marche très bien
$_vt_Value
:=
"N/A"
: (
$_vl_TypeChamp
=
Est une image
)
`conversion base 64 ?
$_vt_Value
:=
"N/A"
Sinon
`$0:=("Internal Error";"Unkown Fieldtyp - cannot handle";$fieldname)
Fin de cas
DOM_set_ElementWithValue (
$_vt_RefElement
;
$_vt_TagName
;
$_vt_Value
)
Fin de si
Fin de boucle
Commentaires
La routine xmlw_Si_ChampBinaire nous sert à filtrer les champs binaires que nous ne pouvons pas facilement convertir en texte. Une solution consisterait à utiliser un encodage en base64 grâce à la nouvelle commande de la version 2004, ENCODER.
Comme pour les noms de tables, nous prétraitons les noms de champs dans la routine XMLw_Replace_Char. Par exemple, le nom du champ “[CD]Date Stock« devient “DateStock“. 4D n’effectue pas automatiquement ce traitement, or les espaces étant interdits en XML dans les noms de champs, cela se traduirait par un document XML mal-formé et donc inexploitable.
Nous rajoutons également un préfixe (le nom de la table) au nom du champ, ainsi “[CD]Date Stock« devient réellement “CD.DateStock« dans le document XML produit. Dans le cadre de cet exemple, cela n’a pas réellement d’intérêt. Dans une version plus évoluée pouvant mixer au sein d’un même document XML des champs provenant de plusieurs tables, il pourrait se produire des conflits entre des champs portant le même nom dans des tables différentes. Nous passons ici d’un nom local “ID« par exemple à un nom global “Table1.ID« qui ne peut être confondu avec un autre nom global possédant un nom local identique, “Table2.ID« par exemple. Une solution plus canonique par rapport à XML consisterait à utiliser des espaces de noms différents pour chacune des tables.
Cette routine n’est pas optimisée. Il serait plus efficace d’analyser une fois pour toutes la structure de la table, et construire un tableau en mémoire contenant les éléments nécessaires pour la génération de la structure XML correspondante et d’utiliser ce tableau pour chaque enregistrement. Ici, l’analyse de la table est répétée pour chaque enregistrement.
Méthode DOM_set_ElementWithValue▲
C’est la méthode qui se charge de créer un élément simple et sa valeur en un seul appel.
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.
` ----------------------------------------------------
` Nom utilisateur (OS) : christophe Keromen
` Date et heure : 30/06/04, 18:00:36
` ----------------------------------------------------
` Methode : DOM_set_ElementWithValue
` Description
` écrit un élément avec sa valeur
`
` Parametres
`$1:TEXTE:Ref Element Parent
`$2:TEXTE:Nom element à créer
`$3:TEXTE:Valeur element à créer
`$0:TEXTE:Ref Element créé
` ----------------------------------------------------
C_TEXTE
(
$1
)
C_TEXTE
(
$_vt_RefParent
)
$_vt_RefParent
:=
$1
C_TEXTE
(
$2
)
C_TEXTE
(
$_vt_NomElement
)
$_vt_NomElement
:=
$2
C_TEXTE
(
$3
)
C_TEXTE
(
$_vt_ValeurElement
)
$_vt_ValeurElement
:=
$3
C_TEXTE
(
$0
)
C_TEXTE
(
$_vt_RefElement
)
$_vt_RefElement
:=
""
$_vt_RefElement
:=
DOM Creer element XML
(
$_vt_RefParent
;
$_vt_NomElement
)
DOM ECRIRE VALEUR ELEMENT XML
(
$_vt_RefElement
;
$_vt_ValeurElement
)
$0
:=
$_vt_RefElement
IV. Conclusion▲
Cette note technique vous a présenté deux exemples d’application des nouvelles commandes de génération XML par DOM dans 4D 2004. Il est maintenant facile de publier vers l’extérieur vos données sous une forme standardisée même si l’automatisation de nombreuses tâches par 4D ne dispense pas d’un minimum de connaissance des règles XML.
Nous verrons dans la deuxième partie de cette note qu’il existe d’autres moyens de produire du XML dans la version 2004 de 4D.
V. Base exemple▲
Téléchargez la base exemple.