Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour,
Je travaille en Pb10.5.
J'aimerais savoir s'il est possible de récupérer les données d'un fichier XML avec ses balises dans une Datawindow sans avoir au préalable créé un long et fastidieux template. En résumé, comment récupérer les données d'un fichier XML et son organisation sans avoir, au préalable, défini sa structure.
Merci d'avance
Dernière modification par cantin_jl (16-10-2008 14:57:51)
Hors ligne
Sans template, l'import XML a lieu en postulant que le XML respecte la structure des colonnes de la DW. Le parser XML va extraire les données qu'il lit séquentiellement dans le XML et insérer les données dans la 1ère colonne libre, ou s'il n'y en a plus, la 1ère colonne d'une nouvelle ligne.
Tout marche bien si ton XML n'est pas hierarchique, et tant que les valeurs de ses entités peuvent être castées dans le type des colonnes utilisées...
Dans un cas comme celui-ci, le mieux est de définir une DW external, constituée de string de longueur 0 (ce qui signifie pas de longueur max).
Evidemment, il y a des tonnes de cas dans lesquels cela ne marchera pas... Désolé, il n'y a pas de solution toute faite. C'est comme dans les autres langages: si tu connais la structure, tu l'encode, sinon tu passe par le DOM... Et en PB tu as PBDOM qui te permet de parser un XML de format inconnu.
Tu peux ainsi générer un template grace a PBDOM, pour automatiser ton import DW (qui est beacoup plus performant que le DOM).
Satisfait?
Hors ligne
Merci pour cette réponse.
Puis-je me permettre de demander un exemple d'utilisation de la "bête" (lecture d'un fichier XML)?
Merci d'avance.
Hors ligne
Tu peux te permettre, mais je ne pourrai rien pour toi aujourd'hui, je suis en clientèle...
De toute facon, il n'y a rien de spécial à faire: tu prend un XML super simple, et une dw external avec des colonnes de type string suffisamment grande, puis un dw_control.import(xml!,...)
Je sais plus vraiment, j'ai pas PB ici
Bonne chance:fra:
Hors ligne
Bon, après quelques recherches, voila à quoi ressemble mon code :
Code test présent dans un bouton
dw_datas.ImportFile(XML!,"C:\TEMP\snecma_xml\ORDER_004244_875137") long ll_ret ll_ret = XMLParseFile("C:\TEMP\snecma_xml\ORDER_004244_875137.xml", ValNever!) PBDOM_Builder lpbdom_Builder PBDOM_Document lpbdom_Doc PBDOM_Object lpbdom_Obj[] PBDOM_Attribute lpbdom_Attr[] PBDOM_Element lpbdom_Root integer li_Counter, li_Max string ls_Text // Create PBDOM Builder lpbdom_Builder = CREATE PBDOM_BUILDER TRY // Import File and generate XML Document lpbdom_Doc = lpbdom_Builder.BuildFromFile("C:\TEMP\snecma_xml\ORDER_004244_875137.xml" ) CATCH (PBDOM_Exception lpbdom_Except) // Error Handling goes here, MessageBox( "PBDOM_Exception", lpbdom_Except.GetExceptionCode()) RETURN END TRY // Get 1st Level data lpbdom_Doc.GetContent( lpbdom_Obj ) wf_lecture_xml(lpbdom_Obj, 0)
Détail fonction wf_lecture_xml
PBDOM_Object lpbdom_Children[] PBDOM_Attribute lpbdom_Attr[] PBDOM_Element lpbdom_Element long ll_Handle integer li_Counter, li_Max, li_AttrCounter, li_AttrMax string ls_Disp li_Max = UpperBound(apbdom_Obj) // Loop through all elements in the array FOR li_Counter = 1 TO li_Max ls_Disp = "" // Get tag information depeding on type of entry CHOOSE CASE apbdom_Obj[li_Counter].GetObjectClassString() CASE "pbdom_processinginstruction" ls_Disp = ": " + apbdom_Obj[li_Counter].DYNAMIC GetData() CASE "pbdom_text" ls_Disp = ": " + apbdom_Obj[li_Counter].DYNAMIC GetText() CASE "pbdom_element" // An element might have attributes lpbdom_Element = apbdom_Obj[li_Counter] IF lpbdom_Element.HasAttributes() THEN lpbdom_Element. GetAttributes(lpbdom_Attr) li_AttrMax = UpperBound(lpbdom_Attr) // Loop through all attributes FOR li_AttrCounter = 1 TO li_AttrMax ls_Disp = ls_Disp + lpbdom_Attr[li_AttrCounter].GetName()+"=" + lpbdom_Attr[li_AttrCounter].GetText()+ " " NEXT ls_Disp = ": " + ls_Disp END IF CASE ELSE ls_Disp = ": " + apbdom_Obj[li_Counter].GetText() END CHOOSE // Display name + additional information ls_Disp = apbdom_Obj[li_Counter].GetName()+ls_Disp ll_Handle=tv_1.InsertItemLast(al_Parent,ls_Disp,0) // if object has children call the same function IF apbdom_Obj[li_Counter].HasChildren() THEN apbdom_Obj[li_Counter].GetContent(lpbdom_Children) wf_lecture_xml(lpbdom_Children,ll_Handle) tv_1.ExpandItem(ll_Handle) END IF NEXT RETURN
Cela me permet de mettre le contenu du fichier XML dans un TreeView.
J'espère que cet exemple sera utile à quelqu'un d'autre.
Finalement PBDOM, c'est bien mais pas assez documenté.
Merci à ceux qui m'ont aidé.
Hors ligne