Jump to page: 1 25  
Page
Thread overview
JSON'a başlangıç
Mar 25, 2012
zafer
Mar 26, 2012
Salih Dinçer
Mar 27, 2012
zafer
Mar 27, 2012
zafer
Mar 27, 2012
Ronin
Mar 27, 2012
zafer
Mar 30, 2012
zafer
Mar 30, 2012
Salih Dinçer
Mar 31, 2012
Salih Dinçer
Mar 31, 2012
Salih Dinçer
Mar 31, 2012
Salih Dinçer
Mar 31, 2012
Salih Dinçer
Apr 02, 2012
zafer
Apr 03, 2012
zafer
Apr 03, 2012
Salih Dinçer
Apr 04, 2012
zafer
Apr 04, 2012
Salih Dinçer
Apr 04, 2012
zafer
Apr 05, 2012
Salih Dinçer
May 22, 2012
zafer
May 22, 2012
Salih Dinçer
May 23, 2012
zafer
May 23, 2012
Salih Dinçer
May 23, 2012
zafer
May 24, 2012
zafer
May 22, 2012
Salih Dinçer
May 22, 2012
Salih Dinçer
March 25, 2012

Malum KelimeMatik projesini konsol tabanlı olarak yeniden yazmaya karar verdim. Bu aşamada bir takım bilgileri saklamak için kullandığım XML yapısındaki dosya sistemini uzun zamandır ilgimi çeken ve son zamanlarda adını sıkça duyduğum JSON yapısı ile değiştirmeyi düşünüyorum.

Bu hem JSON için deneysel bir tecrübe olacak hemde D ve JSON arasındaki samimiyeti daha yakından anlamış olacağım :). Dlang sitesinde şu sayfayı buldum http://dlang.org/phobos/std_json.html ama örnek bulamadım. Bu konuda örnek bulabileceğim bir yer var mı?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 26, 2012

Bu konuya temas ettiğiniz için teşekkürler. XML'i çoğu zaman hantal buluyorum. JSON'u ben de hiç kullanmadım. Bir keresinde GittiGidiyor entegrasyonu için ihtiyaç duymuştum. Ama XML seçeneğim olduğu için çok yavaş da olsa ve bilmediğimden JSON'dan uzak kaldım...:)

Ali hocam, peki JSON verisini ağ üzerinden bir uygulamaya gönderebilir miyiz? Yani D'nin TCP/IP olaylarında yeteneği nasıl bilmediğim için soruyorum. En azından JSON'nun ham verisini görebiliyor muyuz?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 26, 2012

Ben biraz oynadım. İnternette şöyle bir örnek buldum:

'{
"employees": [
{ "firstName":"John" , "lastName":"Doe" },
{ "firstName":"Anna" , "lastName":"Smith" },
{ "firstName":"Peter" , "lastName":"Jones" }
]
}'

Onu "json_deneme" ismiyle kaydettim ve aşağıdaki programla okuyarak 'Çalışan' nesneleri oluşturabildim. Yalnız bu program gözünüzü korkutmasın: içindeki assert'lere ve o kadar değişkene aslında belki de gerek yok.

Aynı programı en sonda daha kısa olarak da göstereceğim.

Anladıklarım şunlar:

  • JSON şu türlerden ve değerlerden oluşuyor: STRING, INTEGER, FLOAT, OBJECT, ARRAY, TRUE, FALSE, NULL

  • Bir ağaç yapısı: bazı elemanlar başka elemanlar içerebiliyorlar.

  • std.json, verilen dizgiyi tarıyor ve JSONValue'lardan oluşan bir ağaç oluşturuyor.

  • Bu ağacın hangi dalında ne olduğunu bilmek ve öyle olduğunu beklemek programın işi. Ne de olsa dosyanın içinde örneğin 'Çalışan' nesnelerini oluşturacak olan isim ve soyad bilgileri var. Yani program bu yapıyı bekliyor. Zaten assert'leri de bu beklentimi göstermek için koydum.

  • JSONValue'nun şu üyeleri her JSON türüne uygun bir tür döndürüyor. Üyeler ve türleri şöyle (bunları /usr/include/d/dmd/phobos/std/json.d içinde de görebiliyorum):

               string                          str;
               long                            integer;
               real                            floating;
               JSONValue[string]               object;
               JSONValue[]                     array;

Yukarıdaki JSON belgesini "json_deneme" ismiyle kaydedin ve şu programla deneyin. Dediğim gibi, ben kendim de anlayabilmek için JSONValue'ları açık açık yazdım:

import std.stdio;
import std.json;
import std.conv;
import std.file;

struct Çalışan
{
   string firstName;
   string lastName;
}

void main()
{
   auto içerik = to!string(read("json_deneme"));
   JSONValue belgeJson = parseJSON(içerik);
   assert(belgeJson.type == JSON_TYPE.OBJECT);
   JSONValue[string] belge = belgeJson.object;

   JSONValue çalışanlarJson = belge["employees"];
   assert(çalışanlarJson.type == JSON_TYPE.ARRAY);
   JSONValue[] çalışanlar = çalışanlarJson.array;

   foreach (çalışanJson; çalışanlar) {
       assert(çalışanJson.type == JSON_TYPE.OBJECT);
       JSONValue[string] çalışan = çalışanJson.object;

       JSONValue firstNameJson = çalışan["firstName"];
       assert(firstNameJson.type == JSON_TYPE.STRING);
       string firstName = firstNameJson.str;

       JSONValue lastNameJson = çalışan["lastName"];
       assert(lastNameJson.type == JSON_TYPE.STRING);
       string lastName = lastNameJson.str;

       auto ç = Çalışan(firstName, lastName);
       writeln("Nesne oluşturduk: ", ç);
   }
}

Bu da programın kısa hali:

import std.stdio;
import std.json;
import std.conv;
import std.file;

struct Çalışan
{
   string firstName;
   string lastName;
}

void main()
{
   auto içerik = to!string(read("json_deneme"));

   JSONValue[string] belge = parseJSON(içerik).object;
   JSONValue[] çalışanlar = belge["employees"].array;

   foreach (çalışanJson; çalışanlar) {
       JSONValue[string] çalışan = çalışanJson.object;

       string firstName = çalışan["firstName"].str;
       string lastName = çalışan["lastName"].str;

       auto ç = Çalışan(firstName, lastName);
       writeln("Nesne oluşturduk: ", ç);
   }
}

Bu da programın çıktısı:

'Nesne oluşturduk: Çalışan("John", "Doe")
Nesne oluşturduk: Çalışan("Anna", "Smith")
Nesne oluşturduk: Çalışan("Peter", "Jones")
'

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 27, 2012

Alıntı (Salih Dinçer):

>

Ali hocam, peki JSON verisini ağ üzerinden bir uygulamaya gönderebilir miyiz? Yani D'nin TCP/IP olaylarında yeteneği nasıl bilmediğim için soruyorum. En azından JSON'nun ham verisini görebiliyor muyuz?

Soru Ali'ye gelmiş ama bende bildiklerimi paylaşayım istedim. Geçenlerde D forumları için yazılmış bir uygulamanın kodları paylaşılmıştı. Sanırım dlang.org sitesindeki forum uygulamasının kodlarıydı, bu kodlardan hareketle ağ üzerinde D ile güzel işler yapılabilir diye düşünüyorum.

Diğer taraftan JSON temelde bir veri aktarım yöntemi diye biliyorum, özellikle JavaScript ile çok kullanılıyor ayrıca yapısı itibarı ile XML'e göre daha az yer kaplamasıda bir başka avantajı, ancak şu zamanda bilgim benimde sınırlı, bakalım üzerinde oynamaya devam ediyorum.. beklerim, birlikte oynayalım ;-)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 27, 2012

Ali yine senin verdiğin harika bilgiler sayesinde JSON konusunda hızla ilerliyorum. Aslında senin oyununa katılmak istiyordum ama dosya dilini görünce ben bir şeyler hazırlamaya karar verdim. Hem oyuna belki yeni oyuncaklarda katmak daha keyfli olur diye düşündüm. Önce oyuncaklarımızı ortaya bir dökelim. JSON dosyamız (uyeler.json);

Alıntı:

>

{
"Uyeler":
[
{ "KullaniciAdi":"acehreli", "AdiSoyadi":"Ali Çehreli", "MesajSayisi": 980 },
{ "KullaniciAdi":"erdem", "AdiSoyadi":"Bilinmez", "MesajSayisi": 100 },
{ "KullaniciAdi":"Mengu", "AdiSoyadi":"Bilinmez", "MesajSayisi": 100 },
{ "KullaniciAdi":"Salih Dinçer", "AdiSoyadi":"Salih Dinçer", "MesajSayisi": 300 },
{ "KullaniciAdi":"zafer", "AdiSoyadi":"Zafer Çelenk", "MesajSayisi": 250 }
]
}

Şimdi birde kodlarımızı buraya alalım ki oyun daha keyifli olsun.

module main;

import std.stdio;
import std.conv;
import std.file;
import std.json;
import std.container;

class ForumUyesi
{
   string kullaniciAdi;
   string adiSoyadi;
   int mesajSayisi;

   this(string kullaniciAdi, string adiSoyadi, int mesajSayisi)
   {
       this.kullaniciAdi = kullaniciAdi;
       this.adiSoyadi = adiSoyadi;
       this.mesajSayisi = mesajSayisi;
   }
}

void main()
{
   SList!(ForumUyesi) listeForumUyeleri;

   string icerik = to!string(read("uyeler.json"));

   JSONValue[string] uyeListesi = parseJSON(icerik).object;

   JSONValue[] uyeler = uyeListesi["Uyeler"].array;

   foreach (uyeBilgisi; uyeler)
   {
       JSONValue[string] uye = uyeBilgisi.object;

       auto forumUyeleri = new ForumUyesi(uye["KullaniciAdi"].str, uye["AdiSoyadi"].str, cast(int)uye["MesajSayisi"].integer);

       listeForumUyeleri.insert(forumUyeleri);
       //writefln("-> %s | %s | %s", uye["KullaniciAdi"].str, uye["AdiSoyadi"].str, cast(int)uye["MesajSayisi"].integer);
   }


   foreach (uye; listeForumUyeleri)
   {
       // insert elemanları listeye ters sırada ekliyor
       writefln("-> %s | %s | %s", uye.kullaniciAdi, uye.adiSoyadi, uye.mesajSayisi);
   }

}

Evet, sorulara geçebilirz sanırım.

JSONValue[string] uyeListesi = parseJSON(icerik).object;

Bu satırda sanırım bir eşleme tablosu hazırlanıyor. Böylece JSON içindeki anahtar-değer çiftleri programlama ortamımıza taşınmış oluyor. Ancal parseJSON() metodunun sonundaki object ifadesine neden ihtiyaç var anlamadım?

foreach (uyeBilgisi; uyeler)
   {
       JSONValue[string] uye = uyeBilgisi.object;

Burada tekrar object olayına girmişiz neden foreach içindeki uyeBilgisi üzerinden bilgileri direk alamıyoruz anlamadım.

cast(int)uye["MesajSayisi"].integer)

son olarak burada integer tipi long'a karşılık geldiği için hata aldım ve cast yaptım. Direk D dilindeki int'e karşılık bir tip yok mu?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 27, 2012

Alıntı (zafer):

>
> JSONValue[string] uyeListesi = parseJSON(icerik).object;
> ```

>
> Bu satırda sanırım bir eşleme tablosu hazırlanıyor. Böylece JSON içindeki anahtar-değer çiftleri programlama ortamımıza taşınmış oluyor. Ancal parseJSON() metodunun sonundaki object ifadesine neden ihtiyaç var anlamadım?

Bu bizim dosyamızdan kaynaklanıyor. Dosya içinde küme parantezleri içindeki *şey*, json dilinde OBJECT. Anlaşılan köşeli parantezler de ARRAY oluyor. O yüzden onun elemanlarına da .object diye erişiliyor.

Alıntı:
>
>
>

foreach (uyeBilgisi; uyeler)
{
JSONValue[string] uye = uyeBilgisi.object;

>

Burada tekrar object olayına girmişiz neden foreach içindeki uyeBilgisi üzerinden bilgileri direk alamıyoruz anlamadım.

Çünkü uyeler JSONValue[] türünde. Onun içindeki her bir JSONValue'nun hangi D türüne karşılık geldiğini bizim seçmemiz gerekiyor. Sen .object demek zorundasın çünkü dosyada köşeli parantezli bölgenin içindeki her eleman küme parantezli bir OBJECT.

Alıntı:

>
> cast(int)uye["MesajSayisi"].integer)
> ```

>
> son olarak burada integer tipi long'a karşılık geldiği için hata aldım ve cast yaptım. Direk D dilindeki int'e karşılık bir tip yok mu?
>

JSON standardını bilmiyorum ama JSONValue'nun içindeki union'dan yaptığım alıntı yukarıda. Orada .integer'ın türü long olarak görünüyor:


           long                            integer;


JSON'un standardına bakıyorum ve sayıların genişlikleri ile ilgili bir bilgi göremiyorum:

 http://www.json.org/

Bence JSON'da sınır yok, onu işleyen programın sınırı olabilir. O yüzden std.json'un yazarı D'nin en büyük türünü seçmiş. Bu durumda senin uyguladığın cast doğru oluyor.

Ali

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
March 27, 2012

Yapısını tam olarak bende bilmiyorum fakat XML' e göre çok daha hızlı işlenebilir, daha kolay okunabilir ve doğal olarak daha az yer kaplayan bir yapısı var. Json' da tüm liste ve ağaç yapılarını gerçekleyebilirsiniz. Alt düğümler için de bir sınırı bulunmuyor.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 27, 2012

Ronin sen daha önce JSON ile çalıştın mı? JSON hakkındaki araştırmalarım sonucu bende senle aynı fikire vardım. XML'e göre çok daha avantajlı duruyor.

Dosya okuma işlemini hallettiğimize göre sıra geldi JSON dosyasına veri ekleme, güncelleme ve silme operasyonlarına. bu konudaki her türlü yardıma açığım :-D

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 30, 2012

Alıntı (zafer:1332916021):

>

Dosya okuma işlemini hallettiğimize göre sıra geldi JSON dosyasına veri ekleme, güncelleme ve silme operasyonlarına. bu konudaki her türlü yardıma açığım :-D

JSON gibi metin düzenindeki dosyalara ekleme ve silme yapılmaz; bütün dosya baştan yazılır. İstenirse yapılabilir tabii ama çok karmaşık olur. Gerekeceğini sanmıyorum.

Çözüm istemediğini biliyorum ama to() şablonunu JSONValue için özelledim. Aşağıdaki gibi opCast() işlecini yazan yapı ve sınıflarla da kolayca kullanılabiliyor:

import std.stdio;
import std.conv;
import std.json;
import std.traits;
import std.exception;
import std.string;

/* Gözlem: Ne to() bizim işlevimiz, ne de JSONValue bizim türümüz. İkisini
* birleştiren böyle bir işleve hakkımız var mı? Veya: Bize mi kalmış? Aslında
* evet, çünkü eklediğimiz bu işlev kendi modülümüzün isim alanına
* ekleniyor. Karışıklık olursa da tam ismiyle ötekisi tam ismiyle örneğin
* std.conv.to diye çağrılabilir.
*
* (Not: C++ olsa std isim alanına bir şey eklenmesine izin verilmez. (Ama
* kendi türlerimizden oluşan std::pair'leri << ile yazdırmak için bazen
* mecbur kalınır.))
*
* UYARI: Eşleme tabloları unutulmuş!
*/
JSONValue to(Hedef : JSONValue, T)(T değer)
{
   JSONValue json;

   static if (isSomeString!T) {
       json.type = JSON_TYPE.STRING;
       json.str = std.conv.to!string(değer);

   } else static if (is (T : long)) {
       static if (is (T == ulong)) {
           /* std.json long türünü kullandığı için ulong'un bazı değerlerini
            * tutamaz. Güvenlik amacıyla bu durumu denetlemek için ulong için
            * ayrı bir 'static if' koşulu yazıyoruz. */
           enforce(değer <= long.max,
                   format("Veri kaybı: Bir %s değeri olan %s, long'a sığamaz!",
                          T.stringof, değer));
       }

       json.type = JSON_TYPE.INTEGER;
       json.integer = değer;

   } else static if (is (T : real)) {
       json.type = JSON_TYPE.FLOAT;
       json.floating = değer;

   } else static if (isArray!T) {
       json.type = JSON_TYPE.ARRAY;

       foreach (eleman; değer) {
           json.array ~= to!JSONValue(eleman);
       }

   } else static if (__traits(compiles, cast(JSONValue)değer)) {
       json = cast(JSONValue)(değer);

   } else {
       static assert(false,
                     "Bu tür JSONValue'ya dönüştürülemez: " ~ T.stringof);
   }

   return json;
}

unittest
{
   import std.typetuple;

   /* ulong'un değer aralığının üst yarısı long'a sığmaz. Onun için ayrıca
    * deniyoruz. */
   to!JSONValue(cast(ulong)0);
   to!JSONValue(cast(ulong)long.max);

   /* Güvenlik gerçekten işe yarıyor mu? */
   bool hataAtıldı_mı = false;
   try {
       to!JSONValue(ulong.max);

   } catch (Exception) {
       hataAtıldı_mı = true;
   }
   enforce(hataAtıldı_mı, "ulong.max için hata atılmadı!");

   /* Her temel tür kullanılabilmeli. */
   alias TypeTuple!(byte, ubyte, short, ushort, int, uint, long, /* ulong, */
                    float, double, real,
                    string, wstring, dstring, char[], wchar[], dchar[],
                    int[])
       Türler;
   foreach (Tür; Türler) {
       to!JSONValue(Tür.init);
   }
}

struct Öğrenci
{
   string isim;
   ulong numara;
   uint[] notlar;

   JSONValue opCast(T : JSONValue)() const @property
   {
       JSONValue[string] üyeler;
       üyeler["isim"] = to!JSONValue(isim);
       üyeler["numara"] = to!JSONValue(numara);
       üyeler["notlar"] = to!JSONValue(notlar);

       JSONValue json;
       json.object = üyeler;
       json.type = JSON_TYPE.OBJECT;
       return json;
   }
}

JSONValue JSONBelgesi()
{
   JSONValue json;
   json.type = JSON_TYPE.OBJECT;
   return json;
}

void main()
{
   auto öğrenciler = [ Öğrenci("Ayşe", 12, [ 90, 100 ]),
                       Öğrenci("Başak", 34, [ 95, 99 ]) ];

   JSONValue belge = JSONBelgesi();
   belge.object["öğrenciler"] = to!JSONValue(öğrenciler);

   writeln(toJSON(&belge));
}

Çıktısı:

'{"öğrenciler":[{"isim":"Ayşe","numara":12,"notlar":[90,100]},{"isim":"Başak","numara":34,"notlar":[95,99]}]}'

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 30, 2012

Alıntı (acehreli):

>
>     JSONValue opCast(T : JSONValue)() const @property
>     {
>         JSONValue[string] üyeler;
>         üyeler["isim"] = to!JSONValue(isim);
>         üyeler["numara"] = to!JSONValue(numara);
>         üyeler["notlar"] = to!JSONValue(notlar);
>
>         JSONValue json;
>         json.object = üyeler;
>         json.type = JSON_TYPE.OBJECT;
>         return json;
>     }
> ```


Her türün opCast() işlecinin yukarıdaki gibi elle yazılması külfetli. __traits'i allMembers ile kullanarak otomatik bir çözüm de bulunabilir.

allMembers hem üye değişkenleri hem de üye işlevleri verir. İşlevleri JSON olarak yazmak istemediğimize göre ayırt etmek gerek. hızlıca denediğimde isCallable'ın çözüm olabileceğini görüyorum ama o da tam çözüm değil çünkü üyelerin bazıları opCall() işlecini yüklemiş oldukları için isCallable sanılabilirler.

Ali

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
« First   ‹ Prev
1 2 3 4 5