C’den XML’e Dönüştürücü
C struct’larını veya typedef’lerini yapıştır. Temiz XML al.
Bu araç ne yapar
C’nin yerleşik bir XML serileştiricisi yok. Bir typedef struct’ı birebir yansıtan bir XML belgesi istediğinde genelde libxml2, Expat çıkarır ya da şeyi karakter karakter elle yazarsın. C’yi buraya yapıştırırsan o ilk yazma turunu atlatırsın — araç; tanımladığın alanlar, iç içe tipler ve dizilerle uyumlu, well-formed XML üretir.
Oyuncak bir alt küme değil, gerçek C okur. typedef struct { char orderId[16]; double totalAmount; OrderItem items[2]; } Order; ile bir C99/C11 designated initializer (Order o = { .orderId = "ORD-4821", ... };) birleşince her member’ın alt eleman olduğu eksiksiz bir <Order>...</Order> ağacına dönüşür. Sabit boyutlu char dizileri (byte dizisi değil) string olarak ele alınır, sayısal tipler literal formunu korur ve <stdbool.h>’den gelen bool çıktıda true / false olur.
Diziler ve iç içe struct’lar elle yazacağın şekilde çıkar. Bir OrderItem items[2], <items><OrderItem/><OrderItem/></items>’e dönüşür ve her eleman açılır. İç içe typedef’ler altlarındaki layout’a kadar çözülür, yani double için bir MoneyAmount aliası hâlâ havada kalan bir referans değil sayısal değer üretir. Initializer’ı olmayan pointer’lar sessizce düşürülmek yerine boş eleman olarak çıkar — çıktıyı, hâlâ eski tüketicilere XML konuşan bir GCC’yle derlenmiş servis için şema şablonu olarak kullanıyorsan çok işe yarar.
Nasıl kullanılır
Üç adım. Tek bir typedef da yapıştırsan, bütün bir header’ı artı initializer’ı da yapıştırsan çalışır.
C’ni yapıştır (ya da örneği dene)
Soldaki editöre istediğin C’yi bırak — bir typedef struct, düz bir struct, bir designated initializer ya da karışımı. #include direktifleri, yorumlar ve #define makroları problem değil; dursun.
Daha temiz bir örnek mi istiyorsun? Örneği Yükle’ye bas; iç içe OrderItem ve Address ile gerçekçi bir Order typedef’ı, C99 designated-initializer sözdizimiyle initialize edilmiş olarak gelir.
Dönüştür’e bas
Yeşil Dönüştür butonuna tıkla. Araç struct’ların üzerinden geçer, typedef’leri çözer, iç içe tipleri ve dizileri açar ve XML’i tek seferde yazar. Çalışırken kısa bir yükleme göstergesi döner.
XML’i kopyala
Sağdaki panel well-formed ve girintili XML’le dolar. libxml2 test fixture’ına, firmware’ının boot’ta okuduğu bir config dosyasına, bir Expat callback testine veya dokümantasyonuna yapıştır.
Gerçekten işe yaradığı yerler
Embedded / firmware config şablonları
Bootloader’lar ve endüstriyel cihazlar genelde XML config’i flash’tan veya SD karttan okur. Config’i anlatan C struct’ını yapıştır, layout’la byte-byte uyan düzenlenebilir bir XML şablonu al.
libxml2 / Expat test fixture’ları
Her parser testi için elle örnek XML yazmak yoruyor. Fixture’ları parser’ının doldurduğu gerçek typedef’lerden üret — fixture’lar ve tipler hep senkron kalır.
Eski XML sistemleriyle konuşmak
Telko, savunma ve sağlıktaki C servisleri iş ortağı sistemlerle hâlâ XML alışverişi yapıyor. Yeni bir struct’ın hat üzerinden gitmesi gerektiğinde, bu araç sen serializer’ı yazmadan önce tam şekli gösterir.
Dokümantasyon ve şema örnekleri
"Tipik bir mesaj" gösteren README ve API referans bölümlerini güncel tutmak, örnek gerçek header’dan üretilince daha kolay. Kodun okuduğu ile dokümanın iddia ettiği arasında drift olmuyor.
Sık sorulan sorular
Birden fazla typedef içeren bütün bir header’ı yapıştırabilir miyim?
Evet. Tam header’ı yapıştır — her typedef struct yakalanır, iç içe tipler inline açılır ve forward-declare edilmiş tipler, tanımları yapıştırdığın metnin ilerisinde göründüğünde çözülür. Layout açısından #include, #define ve yorumlar yok sayılır.
C99 / C11 designated initializer’larını anlıyor mu?
Evet. Order o = { .orderId = "ORD-4821", .items = { ... } }; alan adıyla parse edilir, böylece XML eleman isimleri yazdığınla birebir örtüşür. Struct tanımı aynı yapıştırmada varsa konuma göre aggregate initializer’lar da çalışır — araç, bildirilen üye sırasına göre konumları hizalar. C11 standardının 6.7.9. bölümüne bak.
char dizilerini, enum’ları ve union’ları nasıl ele alıyor?
Sabit boyutlu char dizileri (gerçek C kod tabanlarının neredeyse hepsindeki gelenek) tam sayı listesi olarak değil string olarak render edilir. enum değerleri sayısal değer olarak değil enumerator adıyla yazılır, böylece çıktı okunur kalır. union üyeleri, designated initializer net bir şekilde son atanan varyantı gösteriyorsa o varyant olarak; aktif varyant belirsizse yorumlu boş bir eleman olarak yazılır.
Neden direkt libxml2 veya Expat kullanmıyoruz?
O kütüphaneler runtime serileştirme için sağlamdır ama ilk fixture’ı ya da ilk config şablonunu elle yazmak yine de zaman alıyor. Bu araç o zamanı kurtarır. XML şeklini doğru bulduktan sonra production yolu için libxml2 veya Expat’ı arkasına tak.
Kodum saklanıyor mu?
Kodun dönüşüm için backend’e gönderilir ve kalıcı hâle getirilmez — payload’ı loglamıyoruz. Her zamanki gibi, kaynak hassassa (tescilli protokol, güvenlik kritik firmware vs.) yapıştırmadan önce bir göz at.
C’de pointer, fonksiyon pointer’ı ya da opak tip varsa?
Initializer’ı olan nesne pointer’ları işaret ettiği yere kadar takip edilir. Initialize edilmemiş pointer’lar, fonksiyon pointer’ları ve opak tipler (tanımı görünmeyen struct Foo*) tüm dönüşümü düşürmek yerine boş eleman olarak yazılır. Bu, pointer hedefi serileştirilmiş payload’ın parçası olmayan bir struct için elle XML yazarken yapacağın şeyle aynı.
İşine yarayabilecek diğer araçlar
C’den XML’e dönüştürme yapbozun tek bir parçası. Bunlar iyi eşlik eder: