İçeriğin rss beslemesi kullanımda değil Soru - Cevap Bölümü / Kategori: Programlama

29/04/2010 - 14:02:59 cevap (10) Okunma : 4585 Bu yazıyı 0 kişi tuttu.

AS3: XML veriyi POST eden EVENTlar

Merhaba,

POST yöntemini (method) kullanarak XML veriyi bir API'ye POST ediyorum. Veri boyutu yaklaşık 1,2 MB fazla değil, bir disket (biraz nostalji yapalım) kadar. Ancak düğümler (nodes) 1300'ü aşıyor. Ayrıca başka bir XML şablon ile birleşiyor ve gönderdiğim veriler 5 MB. buluyor. Yine fazla değil öyle değil mi!

Ama olaylar (events) başıma olay oldu..:) Çünkü bir döngü içerisinde kullandığım için 1300 küsür olay kuruluyor ve uygulama göçüyor. Biliyorum, yanlış yapıyorum ama bildiğim tek yöntem bu. Flash en fazla 120 küsür olayı kaldırıyor. AS3'e yeni başladığım için olaylar kafam çok almıyor. Aşağıdaki verdiğim kod örneğinden bana bir çıkış yolu aralayabilir misiniz?

var HATALIgiden:Number = 0;
var DÜZGÜNgiden:Number = 0;
var XMLşablon = <ProductRequest>
    <Authorize>
        <SessionId>FBB1A2FA3AB4CB0DFFD0F3E7A25C5074</SessionId> 
    </Authorize> 
    <Action>insert</Action> 
    <Product>
        <Category/> 
        <Title/>
        <Subtitle/>
        <Count/>
        <Price/>
        .
        .
        .
    </Product>    
</ProductRequest>;

var apiXML:XML = new XML();
var apiYÜKLEYİCİ:URLLoader = new URLLoader();
    apiYÜKLEYİCİ.addEventListener(Event.COMPLETE, XMLçözümle);
    apiYÜKLEYİCİ.load(new URLRequest("http://www.domain.com/api.php"));

function XMLçözümle (olay:Event):void {
apiXML = new XML(olay.target.data);
    for (var i:int =  0; i <= 99; i++) {
        XMLşablon.child("Product").Category.text = apiXML.pr[i].ct.text(); 
        XMLşablon.child("Product").Title = PARÇALA (apiXML.pr[i].pn.text(),true);
        XMLşablon.child("Product").Subtitle = PARÇALA (apiXML.pr[i].pn.text(),false);
        XMLşablon.child("Product").Count.text = gg.pr[i].apiXML.text();
        XMLşablon.child("Product").Price.text = gg.pr[i].apiXML.text();
        XMLşablon.child("Product").PhotoTypes.Photo.URL.@bigPhoto = "http://www.domain.net/big/" + gg.pr[i].pp.text();
    XMLyolla();
        XMLşablon.child("Product").Category = <Category/>;
        XMLşablon.child("Product").Count = <ProductCount/>;
        XMLşablon.child("Product").Price = <Price/>;
        XMLşablon.child("Product").PhotoTypes.Photo.URL = <URL bigPhoto=""/>  
    }
}

function XMLyolla():void {
var XMLyükleyici:URLLoader = new URLLoader();
    XMLyükleyici.addEventListener(Event.COMPLETE, Durumİzle, false, 0, true);
var XMLtalep = new URLRequest("https://api.domain.com/users"); 
    XMLtalep.requestHeaders = [new URLRequestHeader('Content-Type', 'application/xml')] 
    XMLtalep.data = '<?xml version="1.0" encoding="iso-8859-9"?>' + XMLşablon.toXMLString(); 
    XMLtalep.method = URLRequestMethod.POST; 
    try {
        XMLyükleyici.load(XMLtalep);
    } catch (e:Error) {
        trace(e);
    }
}

function Durumİzle (e:Event):void {
var gidenXML:XML = new XML();
    gidenXML = new XML(e.target.data);
    if(gidenXML.AckCode=="Failure")   {HATALIgiden++; xSay1.text = HATALIgiden.toString();}
    if(gidenXML.AckCode=="Success") {DÜZGÜNgiden++; xSay2.text = DÜZGÜNgiden.toString();}
    hata1.text = gidenXML.Errors.Error.ErrorCode
    hata2.text = gidenXML.Errors.Error.Message
    zaman.text = gidenXML.TimeElapsed;
    // i++;
}

Kabül ediyorum olay(ları) çok karıştırmışım. Biraz basitleşitirirsek aslında iki olay var:

  • apiYÜKLEYİCİ (verinin bulunduğu XML'i yükleyen ve XMLçözümle'ye bağlayan)
  • XMLyükleyici (veri şablonla birleştirildikten sonra XMLyolla ile gönderen ve Durumİzle'ye bağlayan)

Ama dikkat etiyseniz ikinci olay(event) aslında bir döngü içinde. Sanırım bu büyük bir yanlış çünkü döngü eğer yüzü aşarsa uygulama kararsızlaşıyor. Aklıma gelen tek çözüm döngüyü kaldırıp "i" değişkenini Durumİzle için de arttırmak? Ama tekrar XMLçözümle'ye gönderemiyorum.

Arkadaşlar bu ilk sorum, lütfen yardım edin. Bu uygulama ile bir haftadır uğraşıyorum ve artık bitirip diğer işlerimi yapmam lazım.

Teşekkürler...

adres selcukbozdag profilini göster
Selcuk.Bozdag 19.11.2008 17:58:55
En iyi cevap mı ?

Oncelikle MMIstanbul'a hosgeldin.

URLLoader yerine HTTPService kullanarak sorunu cozebilirsin. Dongu kurmana gerek yok bence.

XML'i su sekilde yollayabilirsin:


  var service:HttpService;

  service = new HTTPService();
  service.url = "http://www.domain.com/api.php";
  service.method = "POST";
  service.addEventListener("result", resultFunc);
  service.addEventListener("fault", errorFunc);
  service.send( apiXML );

Sonucu ve hatayi ele alirken:



function resultFunc(result:ResultEvent):void {
 // sonuc
}

function errorFunc(result:FaultEvent):void {
 // hata
}

adli iki fonksiyonu tanimlarsin.

XML'i alirken de baska bir HTTPService tanimlaman ve resultFormat'i "xml" olarak belirtmen yeterli olacaktir. Aklima gelen yontem bu oldu.

"Over-engineering" e gerek yok, sorun sadece XML alip vermek.

adres Salih Dincer profilini göster
Salih Dincer 19.11.2008 21:29:02
En iyi cevap mı ?

Hoş bulduk...

Her türlü öneriye açığım. Ama sorun şu ki XML'i her hangi bir kaynaktan çekip bunu başka bir adrese tek seferde gönderemiyorum. Kaynak XML'in her düğüm içindeki veriyi alıp Flash içindeki şablonla API'nin istediği biçime dönüştürüyorum. Sonra ne kadar düğüm varsa (~1300 adet) o kadar XML'i POST ediyorum.

Aslında API'nin tüm XML'i yükleyebilme özelliği olsaydı beni hiç uğraştırmazdı. Ancak ne yazık ki böyle bir şey söz konusu değil. O yüzden yardımlarınıza ihtiyaç duydum. Aslında şu an işimi görüyor, ama nasıl! Mesela 1000 tane POST için 9 defa döngüyü tekrar kuruyorum. Başta 0 to 99 iken, sonra 100 to 199 yapıyorum. Ama hiç pratik ve profesyonel olmadığını belirtmeliyim...:(

Teşekkürler...

adres Safakizilkaya profilini göster
Safa kızılkaya 20.11.2008 11:52:13
En iyi cevap mı ?

Kaynak XML dökümanı eğer statikse, düğümler de herhalde statiktir.

Php (ya da ASP) ile mevcut XML dökümanını filtreleyip sonra da API'nın keyfine uygun filtrelenmiş yeni XML dosyasını Flash ile API'ye göndersen? Yani, yeniden XML oluşturma işini Flash'a değil de daha güçlü bir arayüze yıksan?

Şöyle olur:

Flash PHP'ye bağlanır. PHP mevcut XML dökümanını filtreler. Kaydeder. Kaydedilmiş yeni XML'i Flash'a echolar. Flash'ta API'ye echolar.(Flash'a ne gerek varsa:))

Eğer XML dökümanı dinamikse, yani bir veritabanından XML ayıklanıyorsa yine aynı şey olur.

Flash PHP'ye bağlanır. PHP veritabanına bağlanır. VT'deki veriyi API'ye uygun bir biçimde filtreler ve bu verilerden yeni bir XML dökümanı oluşturur. Kaydedilmiş yeni XML'i flash'a echolar. Flash'ta API'ye echolar.(Yine Flash'a ne gerek varsa:))

adres endercan profilini göster
Ender ÇAKIR 20.11.2008 12:45:15
En iyi cevap mı ?

arkadaşlar ben xml"i 2 saniyede bir sürekli yinelenen bir proğram yazdırdım arkadaşıma.fakat benim ise yapmak istediğim bu xml deki değere göre animastonumu çalıştırmak <K1>0</K1> gelen değer 1 ise oynat MC yi 2 ise Durdur 3 ise vb.. fakat yapamadım yardım olursanız çok sevinirim şimdide herkese teşekkürler iyi çalışmalar


  <?xml version="1.0" standalone="yes" ?> 
- <DocumentElement>
- <Tablo>
  <K1>0</K1> 
  <K2>4</K2> 
  <K3>4</K3> 
  <K4>2</K4> 
  <K5>3</K5> 
  <K6>0</K6> 
  </Tablo>
  </DocumentElement>
adres selcukbozdag profilini göster
Selcuk.Bozdag 20.11.2008 17:48:35
En iyi cevap mı ?

@salih eger API'ye XML'i oldugu gibi yuklemen mumkun degilse 1300 kere POST yaparken uygulaman icin baska seyleri cozmen gerek.

Birincisi ActionScript'de multithreading (benim bildigim kadariyla) yok. Eger olsaydi farkli thread'ler acip 1300 sayisini kucuk parcalara bolup es zamanli calistirabilirdin. Google'da multithreading uzerine ActionScript icin bir baktim karsima "sozde-multithreading" (PseudoMultithreading) diye birsey cikti. http://blogs.adobe.com/aharui/2008/01/threadsinactionscript_3.html. Buradaki ornegi bir incele belki isine yarar.

Dongu eger yuzu asarsa uygulama kararsizlasiyor.

Burada neyi anlatmaya calistin? Nasil kararsizlasiyor? Ilk paragrafinda da uygulama "cokuyor" demistin.

Bunun nedeni network'e bir anda yuklenip darbogaz yaratman da olabilir. 5 MB'lik veri TCP/IP basliklariyla beraber epey bir veri oluyor. Ve sen bu TCP/IP basliklarini her 1300 POST'da mecburen tekrarliyosun. Belki, geciktirebilirsin. Mesela, her 10 POST'da bir saniye ara ver. Boylece TCP katmaninda paketlerin iletilmesi icin bir aralik yaratmis olursun. Bu sadece bir varsayim. Karsindaki API'nin cevap gondermesine zaman tanimak icin.

Ikincisi, en iyisi API'yi yazana bir email gonderip derdini anlat, gerekli duzeltmeleri ve eklemeleri yapsin.

Ben olsam ikincisini secerdim...

adres Salih Dincer profilini göster
Salih Dincer 20.11.2008 19:59:22
En iyi cevap mı ?

Aslına bakarsanız API'nin değişimi şu an zor gözüküyor. Çünkü dünyada milyonlarca kişi bu şekilde kullanıyor. Bildiğiniz eBay API'si aslında. Bana gönderdikleri ise basit bir Java kodu. Yani tek bir ürün POST ediyor.

Flash'da yapmama gelince bu şekilde kolayıma gitti de diyebilirim. PHP ile daha kolayı varsa yapabilirim. Aslında eBay'ın sitesinde örnek PHP kodlar var. Ama benim kullandığım sistem eBay'dan biraz farklı. Yani o kodlar uymuyor. Onları çözmekte çok vaktimi alabilirdi.

Bu uygulamada ise asıl sorun döngü içinde her şeyin bir anda olup bitmesi. POST'lar hariç tabi. Yani kısa bir sürede döngü bitip olaylar kuruluyor. Bunu aşamalı veya süreye bağlı nasıl yapılacağını bilmiyorum. Şimdi yine 10 defa 100'erli yükleme yaptım. Gerçekten çok baş belası bir şey. Öyleki Flash'ı kapayıp açmadan uygulama tekrar çalışmıyor. Herhalde hafıza taşıyor bir şeyler oluyor...:(

adres Safakizilkaya profilini göster
Safa kızılkaya 21.11.2008 01:25:36
En iyi cevap mı ?
Faydalı cevap

Mevlevi dervişleri bile bu kadar dönmeye dayanamaz:)

Binlerce düğümden oluşan bir XML dökümanın olsa bile , bu döküman içerisinden istediğin kadar düğümü, birbirleriyle ilişkili ya da ilişkisiz, basit bir "foreach" sorgusu ile "referans" belirterek bir iki saniyede ayıklar, echo'lar, print'ler, save'lersin.

PHP DOMXPath bunu yapar.

products.xml isminde bir dosyan olsun. Bu dosyada, diyelim ki 10.000 düğüm var. Sen ise bu 10.000 düğüm içerisinde "adobe" markalı ürünleri bulmak ve echolamak istiyorsun. Echo'nun da XML formunda olmasını istiyorsun. Üstelik bu yeni xml formundaki echo, orijinal xml dosyasından farklı root, parent ve child isimlerine sahip olsun.

Şöyle olur:

orijinal products.xml dosyası:


<?xml version="1.0" encoding="utf-8"?>
<products>
<product>
<productname>flash cs4 pro</productname>
<producer>adobe</producer>
</product>
<product>
<productname>printer</productname>
<producer>hp</producer>
</product>
<product>
<productname>laptop</productname>
<producer>samsung</producer>
</product>
<product>
<productname>play station</productname>
<producer>sony</producer>
</product>
<product>
<productname>xbox</productname>
<producer>microsoft</producer>
</product>
<product>
<productname>zune</productname>
<producer>microsoft</producer>
</product>
<product>
<productname>ipod</productname>
<producer>apple</producer>
</product>
<product>
<productname>plasma tv</productname>
<producer>beko</producer>
</product>
<product>
<productname>after effects cs4</productname>
<producer>adobe</producer>
</product>
<product>
<productname>laptop</productname>
<producer>dell</producer>
</product>
<product>
<productname>play station</productname>
<producer>sony</producer>
</product>
<product>
<productname>xbox</productname>
<producer>microsoft</producer>
</product>
<product>
<productname>zune</productname>
<producer>microsoft</producer>
</product>
<product>
<productname>ipod</productname>
<producer>apple</producer>
</product>
<product>
<productname>acrobat 9 pro</productname>
<producer>adobe</producer>
</product>
<product>
<productname>printer</productname>
<producer>hp</producer>
</product>
</products>

products.xml dosyasını tarayan php dosyası ise şu yapıda olur:


<?php
$productfinder = new DOMDocument;
$productfinder->preserveWhiteSpace = false;
$productfinder->formatOutput = true;  
$productfinder->Load('products.xml');
$xpath = new DOMXPath($productfinder);
$query = '//products/product/producer[.="adobe"]';
$elements = $xpath->query($query);
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
echo "<findadobeproducts>\n";
foreach ($elements as $node) {
    echo "<adobeproduct>{$node->previousSibling->previousSibling->nodeValue}" .
         " {$node->previousSibling->nodeValue}</adobeproduct>\n";
}
echo "</findadobeproducts>";
?>

php şöyle bir XML dosyası echolar:


<?xml version="1.0" encoding="utf-8"?>
<findadobeproducts>
<adobeproduct> flash cs4 pro</adobeproduct>
<adobeproduct> after effects cs4</adobeproduct>
<adobeproduct> acrobat 9 pro</adobeproduct>
</findadobeproducts>

Echoyu elde ettiğine göre, API'ye gönderebilirsin.

adres Salih Dincer profilini göster
Salih Dincer 21.11.2008 09:17:50
En iyi cevap mı ?
Echoyu elde ettiğine göre, API'ye gönderebilirsin.

Ama nasıl, bunu ne yazık ki bilmiyorum...:(

Hatta veritabanı benim kontrolümde olduğu için söyledikleriniz ile uğraşmaya bile gerek yok. XML verdiğim diğer yerler gibi tek seferde bunu yapabilirim. Tabi tek sefer derken her ürüne karşılık tek POST gelmeli. Karşıdan "Success" alınca yoluna devam etmeli.

İşte yola devam etmek için hangi otobüse binmeliyim? Bu sefer soru PHP ile alakalı oldu. En iyisi bunu bir PHP forumunda sormalıyım.

Sanırım Flash'da olayları (events) bir döngü kontrolü haricinde sırayla meydana getiremeyeceğim. Bu konuda cevap gelmediğine göre bu imkanlı olmayabilir.

Sizleri cevap verdirerek uğraştırdım, zahmet verdiysem kusura bakmayınız.

Teşekkürler...

adres gokhancelik profilini göster
gökhan çelik 21.11.2008 10:15:55
En iyi cevap mı ?

En iyisi paçalara bölerek göndermen aslında kanımca bunu tek seferde yapman mümkün değil :) sonuç itibari ile bir makine ile çalışıyorsun yanlışmı düşünüyorum ?

adres ecarpar profilini göster
Gökhan erdal Çarpar 31.01.2012 13:32:45
En iyi cevap mı ?

greensock'un xml ler için bir uygulaması mevcut kullanmanızı şiddetle tavsiye ederim. Çözdükten sonra kendinizde şaşırıcaksınız.

Örnek olarak. as 2 versiyonunu kullanmıştım ben..

import com.greensock.dataTransfer.XMLParser; XMLParser.load("ornek.xml", onFinish, null, false, true);

function onFinish($success:Boolean, $parsedObject:Object, $xml:XML) { //This fhunction gets called as soon as the XML loads and gets parsed. if ($success) {

    displayResources($parsedObject);
    showImage($parsedObject);       
    TumXml++;
} else {
    trace(&quot;FAILED to load XML&quot;);
}

} function displayResources($parsedObject:Object):Void { var i:Number; var TumXML= $parsedObject.Firma; for (i = 0; i < TumXML.length; i++) { Adlary[i] = TumXML[i].Adi; Soyadlar[i] = TumXML[i].Soyad ; NUmara[i] = TumXML[i].Numada ;

    }

}

aç-kapa Bu Yazıyı Tutanlar

bu yazıyı tutan kimse yok.

yeni üyelik | şifremi unuttum

üyeler Son Kahramanlar...

stats Kimler Burada? web stats

Son 1 dakika içinde MMIstanbul' da 53 (50 kayıtlı, 3 ziyaretçi) kullanıcı varmış. Login durumda olanlar aşağıda:

...

Blog Bölümü Blogevi.com'a Taşınıyor

Selam arkadaşlar MMIstanbul'da , tasarımcı ve programcıların blog yazılarını "feedleyerek" MMIstanbul okurlarını MMIstanbul dışın ...

7.500'üncü üyemiz Cem Koç!

Neler Yapılabilir?

500 Hatası Hakkında!

Reklam, MMIstanbul ve Yeni Projeler (Durumumuz Bu Tarzında)

coldfusion mysql ubuntu
 
sponsor adobe istanbul