Windev : Parcourir un fichier XML en entier et le charger dans une structure de type arbre en mémoire (DOM)
Voici un code permettant d'effectuer le parcours complet d'un fichier XML et de le charger dans une structure arborescence, un peu à la manière du DOM (http://fr.wikipedia.org/wiki/Document_Object_Model) (En beaucoup plus simple).
Je trouve plus pratique dans certains cas de parcourir ce type d'arbre mémoire, plutôt que d'utiliser les fonctions XML fournies par Windev.
Tout d'abord, dans le code de déclaration de ma fenêtre, je déclare deux structures :
La structure strEl contiendra les noeuds de type "Element", et la structure strAt contiendra les noeuds de type "Attribut".
-Un attribut a un nom et contient une donnée.
-Un élément a un nom, peut contenir une donnée, peut avoir des attributs et peut contenir d'autres éléments.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
//Structure pour les noeuds de type "Attribut"
strAt est une structure
sXPath est une chaîne
sNom est une chaîne
sDonnee est une chaîne
FIN
//Structure pour les noeuds de type "Element"
strEl est une structure
sXPath est une chaîne
sNom est une chaîne
sDonnee est une chaîne
tstAt est un tableau de strAt
tstEl est un tableau de strEl
FIN |
Voici le code parcours et de création de l'arborescence mémoire du fichier XML :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
LOCAL
sDocXml est une chaîne
sXML est une chaîne
sXML = fChargeTexte(SC_SelecteurFichier.SAI_FIC)
sDocXml = "XmlDoc"+DonneGUID(guidBrut)
SI PAS XMLDocument(sDocXml,sXML) ALORS
Erreur(ErreurInfo(errComplet))
RENVOYER Faux
FIN
XMLRacine(sDocXml)
//Déclaration de l'élément racine
stEl est un strEl
ParcoursXML(sDocXml,stEl,Vrai) |
Et le code de la méthode "ParcoursXML" :
Code:
1 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
|
PROCEDURE ParcoursXML(_sDocXML est une chaîne,_stEl,_bRacine est un booléen=Faux)
iPos est un entier
Trace(XMLPosition(_sDocXML))
stEl est un strEl
stat est un strAt
SELON XMLTypeElement(_sDocXML)
CAS XMLBalise
SI XMLFilsExiste(_sDocXML) ALORS
iPos = XMLSauvePosition(_sDocXML)
XMLFils(_sDocXML)
XMLPremier(_sDocXML)
TANTQUE PAS XMLEnDehors(_sDocXML)
ParcoursXML(_sDocXML,stEl)
XMLSuivant(_sDocXML)
FIN
XMLRetourPosition(_sDocXML,iPos)
stEl:sNom = XMLNomElément(_sDocXML)
stEl:sDonnee = XMLDonnée(_sDocXML)
stEl:sXPath = XMLPosition(_sDocXML)
SI _bRacine ALORS
_stEl = stEl
SINON
TableauAjoute(_stEl:tstEl,stEl)
FIN
SINON
stEl:sNom = XMLNomElément(_sDocXML)
stEl:sDonnee = XMLDonnée(_sDocXML)
stEl:sXPath = XMLPosition(_sDocXML)
SI _bRacine ALORS
_stEl = stEl
SINON
TableauAjoute(_stEl:tstEl,stEl)
FIN
XMLSuivant(_sDocXML)
SI XMLTrouve(_sDocXML) ALORS
ParcoursXML(_sDocXML,_stEl)
SINON
RENVOYER Vrai
FIN
FIN
CAS XMLAttribut
stAt:sNom = XMLNomElément(_sDocXML)
stAt:sDonnee = XMLDonnée(_sDocXML)
stAt:sXPath = XMLPosition(_sDocXML)
TableauAjoute(_stEl:tstat,stAt)
XMLSuivant(_sDocXML)
SI XMLTrouve(_sDocXML) ALORS
ParcoursXML(_sDocXML,_stEl)
SINON
RENVOYER Vrai
FIN
AUTRE CAS
RENVOYER Vrai
FIN
RENVOYER Vrai |
Je précise que j'utilise volontairement des structures non dynamiques, malgrès que cela altère la lisibilité du code, car un bug de Windev 15 empêche de visualiser le contenu de structures dynamiques dans le débogueur.
Une fois ma structure récupérée, je peut la parcourir et effectuer des recherches simplement de cette façon :
Code:
1 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
|
//Parcours des éléments contenus dans mon élément racine
POUR TOUT stElFils DE stEl:tstEl
Trace("--------------------------------------")
Trace("Element courant")
Trace("stElFils:sNom = "+stElFils:sNom)
Trace("stElFils:sDonnee = "+stElFils:sDonnee)
Trace("stElFils:sXPath = "+stElFils:sXPath)
Trace("--------------------------------------")
Trace("Parcours des attributs de l'élément courant")
POUR TOUT stAt DE stElFils:tstAt
Trace("stAt:sNom = "+stAt:sNom)
Trace("stAt:sDonnee = "+stAt:sDonnee)
Trace("stAt:sXPath = "+stAt:sXPath)
FIN
Trace("--------------------------------------")
Trace("Parcours des éléments fils de l'élément courant")
POUR TOUT stElFils2 DE stElFils:tstEl
Trace("stElFils2:sNom = "+stElFils2:sNom)
Trace("stElFils2:sDonnee = "+stElFils2:sDonnee)
Trace("stElFils2:sXPath = "+stElFils2:sXPath)
//Et ainsi de suite...
FIN
iIndice est un entier
stElTrouve est un strEl
Trace("--------------------------------------")
Trace("Recherche d'un élément fils de l'élément courant dont le nom est ""Couleur""")
iIndice = TableauCherche(stElFils:tstEl,tcLinéaire,"sNom","Couleur")
SI iIndice <> -1 ALORS
stElTrouve = stElFils:tstEl[iIndice]
Trace("stElTrouve:sNom = "+stElTrouve:sNom)
Trace("stElTrouve:sDonnee = "+stElTrouve:sDonnee)
Trace("stElTrouve:sXPath = "+stElTrouve:sXPath)
FIN
Trace("--------------------------------------")
Trace("Recherche d'un élément fils de l'élément courant possédant un attribut ""Couleur"" dont la valeur est ""Bleu""")
POUR TOUT stElFils2 DE stElFils:tstEl
iIndice = TableauCherche(stElFils2:tstAt,tcLinéaire,"sNom;sDonnee","Couleur","Bleu")
SI iIndice <> -1 ALORS
stElTrouve = stElFils2
Trace("stElTrouve:sNom = "+stElTrouve:sNom)
Trace("stElTrouve:sDonnee = "+stElTrouve:sDonnee)
Trace("stElTrouve:sXPath = "+stElTrouve:sXPath)
SORTIR
FIN
FIN
FIN |
Voilà !
Bonne prog :ccool:
Windev : Parcourir un fichier XML en entier et le charger dans un champ de type Arbre Windev
Voici un code permettant d'effectuer le parcours complet d'un fichier XML et de le charger dans un champ de type Arbre Windev.
Code:
1 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
|
ArbreSupprimeTout(ARB_XML)
LOCAL
sDocXml est une chaîne
sXML est une chaîne
sXML = [
<?xml version="1.0" encoding="ISO-8859-1"?>
<racine>
<element id="1">
<infos Couleur="rouge"/>
<Couleur>rouge</Couleur>
</element>
<element id="2">
<infos Couleur="vert"/>
<Couleur>vert</Couleur>
</element>
<element id="3">
<infos Couleur="bleu"/>
<Couleur>bleu</Couleur>
</element>
</racine>
]
//Avant de passer la chaine XML à la fonction XMLDocument(), il faut éventuellement l'encoder au format UFT8 si elle ne contient pas de déclaration d'encodage (<?xml version="1.0" encoding="ISO-8859-1"?>).
//Dans mon cas, ce n'est donc pas nécessaire.
//sXML = ChaîneVersUTF8(sXML)
sDocXml = "XmlDoc"+DonneGUID(guidBrut)
SI PAS XMLDocument(sDocXml,sXML) ALORS
Erreur(ErreurInfo(errComplet))
RENVOYER Faux
FIN
XMLRacine(sDocXml)
//Déclaration de l'élément racine
ParcoursXML(sDocXml,ARB_XML..Nom) |
Et le code de la fonction "ParcoursXML", un peu modifié par rapport à l'exemple précédent (J'utilise une image "Img_Arobase" pour dissocier les feuilles de l'arbre de type "Element" de celles de type "Attribut") :
Code:
1 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
|
PROCEDURE ParcoursXML(_sDocXML est une chaîne,_sArbreNom est une chaîne)
iPos est un entier
sXMLPosition est une chaîne
sArbreChemin est une chaîne
sXMLDonnee est une chaîne
sXMLPosition = XMLPosition(_sDocXML)
//Enlever le premier SLASH
sArbreChemin = Droite(sXMLPosition,Taille(sXMLPosition)-1)
sArbreChemin = Remplace(sArbreChemin,"/",TAB)
//A utiliser uniquement dans le cas où le XML passé à XMLDocument() ne contient pas de déclaration d'encodage.
//sXMLDonnee = UTF8VersChaîne(XMLDonnée(_sDocXML))
sXMLDonnee = XMLVersTexte(sXMLDonnee)
SELON XMLTypeElement(_sDocXML)
CAS XMLBalise
ArbreAjoute(_sArbreNom,sArbreChemin,aDéfaut,aDéfaut,sXMLPosition)
SI SansEspace(sXMLDonnee) <> "" ALORS
ArbreAjoute(_sArbreNom,sArbreChemin+TAB+sXMLDonnee,"","",sXMLPosition)
FIN
SI XMLFilsExiste(_sDocXML) ALORS
iPos = XMLSauvePosition(_sDocXML)
XMLFils(_sDocXML)
XMLPremier(_sDocXML)
TANTQUE PAS XMLEnDehors(_sDocXML)
ParcoursXML(_sDocXML,_sArbreNom)
XMLSuivant(_sDocXML)
FIN
XMLRetourPosition(_sDocXML,iPos)
SINON
XMLSuivant(_sDocXML)
SI XMLTrouve(_sDocXML) ALORS
ParcoursXML(_sDocXML,_sArbreNom)
SINON
RENVOYER Vrai
FIN
FIN
CAS XMLAttribut
ArbreAjoute(_sArbreNom,sArbreChemin,Img_Arobase,Img_Arobase,sXMLPosition)
SI SansEspace(sXMLDonnee) <> "" ALORS
ArbreAjoute(_sArbreNom,sArbreChemin+TAB+sXMLDonnee,"","",sXMLPosition)
FIN
XMLSuivant(_sDocXML)
SI XMLTrouve(_sDocXML) ALORS
ParcoursXML(_sDocXML,_sArbreNom)
SINON
RENVOYER Vrai
FIN
AUTRE CAS
RENVOYER Vrai
FIN
RENVOYER Vrai |
Voilà !
Bonne prog :ccool: