Pour un projet personnel, il fallait que j'embarque un fichier XML de data supérieur à 500 ko (environ 1Mo). Pour cela, j'utilisais le tag:
<mx:XML id="xmlData" source="fichierXML.xml"/>
Le tag <mw:XML> permet d'inclure directement le XML à la compilation dans le SWF et d'ensuite créer des bind facilement. En testant avec le Flash Player 9.0.45.0, tout se passe bien, le XML est bien compilé avec l'application qui tourne correctement sous Firefox et Internet Explorer 7. Cependant, la compilation prenait beaucoup plus de temps, vraisemblablement pour la compression du XML par Flex.
Après installation du dernier FP (Flash Player 9.0.115.0), l'application ne se lance plus et fait directement un freeze au démarrage du navigateur. Après quelques tests, cela ne se produit que pour des fichiers XML supérieurs à 500ko environ, les fichiers dont la taille est inférieure fonctionnent très bien avec Flash Player 9.0.115.0. Si je déclare une nouvelle variable dans un fichier ActionScript 3 séparé contenant le XML, le navigateur internet plante aussi.
Il semble donc que Flash Player 9.0.115.0 n'accepte plus les variables supérieures à 500ko.
Contourner le problème du Flash Player
Pour contourner facilement ce problème et avoir des fichiers XML embedded > 500ko dans une application Flex, il faut faire passer ce XML comme un "octet-stream" (comme une image), puis faire un "cast" de la Class résultante en XML pour pouvoir profiter des possibilités de bind du XML. Cette méthode présente aussi l'avantage de compiler aussi vite que s'il on embarquait pas un XML, contrairement à une compilation avec le tag <mx:XML>.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal"
verticalAlign="middle"
viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
// fichier xml embed
[Embed(source="xmlSampleFlex.xml",mimeType="application/octet-stream")]
public var dataClass : Class;
[Bindable]
public var xmlInput:XML = XML(new dataClass);
// fonction des combobox permettant de récupérer le label du neoud courant pour afficher uniquement le label dans la CB
private function getLabel(item:Object):String{
var valeur:String = "";
valeur = item.@['name'];
return valeur;
}
private function getClientLabel(item:Object):String{
var valeur:String = "";
valeur = item.client.@['name'];
return valeur;
}
]]>
</mx:Script>
<mx:Panel title="Embedded XML Data (>500ko)" width="600" height="400">
<mx:ComboBox id="cbData" dataProvider="{xmlInput.person}" labelFunction="getLabel"/>
<mx:ComboBox id="cbDataClient" dataProvider="{cbData.selectedItem.project}" labelFunction="getClientLabel"/>
<mx:TextArea text="{'Data from embedded large XML: \n\n'+cbDataClient.selectedItem.short_desc}" width="90%" height="90%" editable="false"/>
</mx:Panel>
</mx:Application>
Télécharger le fichier XML exemple associé (environ 1Mo)
Flex Source Code Download: Télécharger le code source complet de l'application
This movie requires Flash Player 11
23 février 2009
Salut,
Je tiens vraiment à vous remercier pour cet article!! c'est vraiment très intéressent surtout que ça fait des semaines que je cherches une solution à un problème pareil que j'ai rencontré.
Sauf que j'utilise un "HTTPService" qui a comme URL un fichier XML de taille >1MO.
Le résultat récupéré de ce service est enregistré dans un "ArrayCollection" et utiliser une autre classe (en fait je travaille sur le modèle de flexstore
http://examples.adobe.com/flex2/inproduct/sdk/flexstore/flexstore.html
)
Est ce que c'est possible de faire de même pour mon fichier XML et le récupérer dans un "ArrayCollection"??
23 février 2009
Salut,
je suppose que cela fonctionnerai oui, pourrais-tu donner plus d'infos sur ton problème (pense à mettre des balises si tu postes du code, voir ci-dessous), les messages d'erreur etc.
fabien
23 février 2009
Merci pour être aussi rapide!!!
et ben lorsque j'exécute mon application, le navigateur se bloque (j'ai essayé avec FireFox, IE, Opera , puis Flash Player => même résultat )
Après un bout de temps, je recoit le message d'erreur suivant:
Error: Error #1502: La durée d'exécution d'un script excède le délai par défaut (15 secondes).
et je ne peux pas te décrire la façon dont je trouve mes données!! des erreurs partout, lenteur extrême de l'exécution d'une animation simple,...alors que la même application marche très bien avec un fichier XML très petit de taille.
Voici mon code (j'utilise Adobe Flex Builder 3):
23 février 2009
Alors tu arrives bien à récupérer le fichier XML, c'est juste le parse en objets Product qui est long en fait (trop apparemment). Combien tu as de new Product au juste ? essaie de les traiter par lots (par tranches de x Product par exemple) sur l'évènement onEnterFrame, ça te permettra déjà d'avoir une meilleure fluidité.
Mais cela me parait tout de même bizarre car j'ai déjà chargé/parsé des XMLs bien plus gros que cela (20Mo par exemple) en ayant des ralentissement mais sans plantage. Je pense que c'est la conversion de ton noeud entreprise en ArrayCollection qui ralentit le tout. Essaie de laisser ce noeud comme un XML (ou une XMLList, je ne connais pas ta data) et de le traiter avec e4x, ce sera sûrement plus rapide et plus lisible
Fabien
23 février 2009
j'ai exactement 2027 Produits à créer!!!
Oui, je vais essayer ça, même si je suis encore débutant en ça.
Donc, je laisse le "HTTPService" récupérer les données du même fichier, j'ajoute (resultFormat="e4x") ??
là je doit faire beaucoup de changement car il y a d'autres "components" qui utilisent des méthodes relatives aux "ArrayCollection"!! C'est vraiment efficace??
23 février 2009
Et bien il y aura toujours l'ArrayCollection qui sera remplie comme vous le faites actuellement, c'est juste le type de parcours qui diffère. Ce sera des for (ou des for each, c'est mieux) au lieu d'un gros while avec un curseur.
23 février 2009
S.V.P vous n'avez pas un exemple par hasard?
23 février 2009
Bon voila un exemple fait en 2 minutes:
Quelques explications:
Comme dans votre cas, j'appelle mon HTTPService pour charger le XML. Une fois qu'il est chargé, il passe dans la méthode de result, ici productServiceResultHandler. Je fais ensuite un cast de ma valeur en XML (pour être sur mais normalement, le résultat est déjà XML). Je boucle ensuite sur mes noeud "product" de mon xml. Ici, result.product me renvoie une XMLList contenant tous mes noeuds "product". Ensuite, je construit un Object (bon vous, vous avez un type Project qui contient des propriétés comme un Object donc c'est la même chose). J'assigne les propriétés de cet objet et je le met dans mon ArrayCollection avec un addItem. Pour info, voici mon XML (plus court, mais c'est pareil):
23 février 2009
Fabien...sérieusement vous me sauvez là!!
Merci énoooooormément!!
24 février 2009
oh là là!!
j'ai cru que ça marche mais rien n'a changé en fait!!
j'ai mis ceci:
=> même résultat qu'avant!!!!!!!
24 février 2009
C'est étrange. Bon et bien pour empêcher que l'application freeze, vous pouvez lancer ce traitement dans un pseudo thread AS3:
http://blogs.adobe.com/aharui/2008/01/threads_in_actionscript_3.html
Tout est expliqué sur cette page
24 février 2009
:-\ je suis bloqué là,
est ce que vous pouvez me donnez votre e-mail pour que vous puissiez voir mieux ce que j'ai?
Je suis vraiment coincé là
le mien c'est gz_youssef@hotmail.com
Merci!
24 février 2009
fnicollet gmail.com, c'est marqué en bas de la page