Neredeyse her entegrasyonun ortak paydası: XML/JSON

troiada-http-istekleri ve troiada-integration-endpoint yazılarında dış sistemlerle konuşmaktan bahsetmiştim; hemen hepsinin ortak noktası, verinin XML ya da JSON formatında taşınması. TROIA'nın bu formatlarla çalışmak için sunduğu araçlar, basit bir dönüşümden şema doğrulamaya kadar geniş bir yelpazede.

Hızlı dönüşüm: CONVERTXMLJSON

CONVERTXMLJSON({girdi}, 'JSON');   /* XML -> JSON */
CONVERTXMLJSON({girdi}, 'XML');    /* JSON -> XML */

XML'den JSON'a çevrilirken, XML özniteliklerinin (attribute) önüne @ karakteri ekleniyor — bu, "JSON çıktısında beklenmedik @ önekli alanlar görüyorum" şaşkınlığının cevabı genelde budur. JSON'dan XML'e çevirirken 'NOTYPEHINT' ya da 'JSONPREFIX' gibi opsiyonel parametrelerle tip ipucu ekleme davranışı kontrol edilebiliyor.

Yapıyı hızlıca keşfetmek: READXMLSTRUCTURE

Elinize hiç tanımadığınız bir XML geldiğinde, elle ayrıştırma haritası yazmadan önce yapısını görmek isteyebilirsiniz:

READXMLSTRUCTURE {xmlicerigi} TO {hedeftablo};

Bu, XML'i analiz edip her elemanın ID'si, ebeveyn ID'si, eleman adı, yolu (path), değeri, iç içe geçme seviyesi ve öznitelik olup olmadığı gibi bilgileri bir tabloya döküyor — yeni bir XML formatıyla ilk kez çalışırken elle inceleme yapmaktan çok daha hızlı bir keşif yöntemi.

Haritalı ayrıştırma: karmaşık/tekrarlayan yapılar için

CREATEXMLMAP {haritaadi};

MAP ELEMENT {elemanadi} AS [XMLTABLE | XMLROOTTABLE] {tablo} IN {haritaadi};
MAP ATTRIBUTE {oznitelik} OF {eleman} AS XMLCOLUMN {kolon} IN {haritaadi};
MAP CHILD {cocuk} OF {eleman} AS XMLCOLUMN {kolon} IN {haritaadi};
MAP PCDATA OF {eleman} AS XMLCOLUMN {kolon} IN {haritaadi};

PARSEXML {dosyayolu} USING {haritaadi};
CONVERTXMLTABLE {xmltablo} INTO {tablo} FROM {haritaadi};

Bu yaklaşım, aynı yapıdaki XML'i tekrar tekrar (örneğin günlük bir entegrasyon dosyası) işleyecekseniz mantıklı — haritayı bir kez tanımlayıp her seferinde yeniden kullanıyorsunuz.

Haritasız, hızlı ayrıştırma

Basit, tek seferlik ihtiyaçlar için harita tanımlamadan doğrudan ayrıştırabilirsiniz:

PARSEXML TEXT {xmlmetni} INTO {tabloadi};
PARSEXML {dosyayolu} INTO {tabloadi};

troiada-http-istekleri yazısındaki CALLWEBSERVICE örneğinde tam olarak bu yöntemi kullanmıştım.

Doğrulama ve biçimlendirme

VALIDATEXML {validatoryolu} {xmlyolu} WITH {tip} [TO {detaylar}];

Schematron tabanlı doğrulamayı destekliyor; sonuç SYS_STATUS/SYS_STATUSERROR'a düşüyor. Ayrıca WRAPXML(STRXML) bir XML string'ini düzgün girintili ve XML bildirimi (declaration) eklenmiş haline getiriyor — loglama ya da hata ayıklama sırasında ham, tek satırlık bir XML'i okunabilir hale getirmek için kullanışlı. CLEARDOCUMENT(STRXML, 'ELEMENT') ise belirtilen elemanı XML yapısından temizliyor — örneğin loglamadan önce hassas bir alanı XML'den çıkarmak istediğinizde.

Gerçek bir örnek: gelen bir sipariş XML'ini haritayla ayrıştırmak

/* Tekrarlayan sipariş XML formatını haritayla tabloya aktarır. */
LOCAL:
    TABLE SIPARISKALEMLERI(URUNKODU CHAR(30), MIKTAR DECIMAL);

CREATEXMLMAP SIPHARITA;
MAP ELEMENT 'Kalem' AS XMLTABLE SIPARISKALEMLERI IN SIPHARITA;
MAP CHILD 'UrunKodu' OF 'Kalem' AS XMLCOLUMN 'URUNKODU' IN SIPHARITA;
MAP CHILD 'Miktar' OF 'Kalem' AS XMLCOLUMN 'MIKTAR' IN SIPHARITA;

PARSEXML '*C:\Entegrasyon\siparis.xml' USING SIPHARITA;
CONVERTXMLTABLE XMLTABLOSU INTO SIPARISKALEMLERI FROM SIPHARITA;

Sık yapılan hatalar

  • @ önekli JSON alanlarını "bozuk veri" sanmak — bu, XML özniteliklerinin JSON'a çevrilme kuralı; hedef sistemin bu önekle geldiğini bilmediğiniz alanlar için ayrıştırma tarafında sürpriz yaratmasın diye önceden test edin.
  • Tek seferlik bir ihtiyaç için harita tanımlamaya uğraşmak — küçük, değişmeyen bir XML için PARSEXML TEXT ... INTO genelde yeterli; CREATEXMLMAP asıl değerini tekrarlayan, karmaşık yapılarda gösteriyor.
  • Doğrulamadan geçmeyen XML'i ayrıştırmaya çalışmak — özellikle harici bir sistemden gelen veri güvenilmiyorsa, PARSEXML çağırmadan önce VALIDATEXML ile temel bir kontrol yapmak, ayrıştırma sırasında anlaşılmaz hatalar almaktan daha iyi bir teşhis deneyimi sağlar.
  • Loglarken hassas veriyi XML içinde bırakmak — CLEARDOCUMENT ile hassas alanları (şifre, kimlik numarası gibi) loglamadan önce temizlemeyi unutmak, log dosyalarının istemeden hassas veri içermesine yol açar.

Sıradaki adım

FTP üzerinden dosya transferini (MAKEFTPCONNECTION, FTPDOWNLOAD, FTPUPLOAD) bir sonraki yazıda ele alacağım — genelde XML/JSON dosyalarının bir sistemden diğerine taşınma yollarından biri de budur.