Node.js İle XML-JSON İşlemleri

Daha önce WordPress eklentisi XML2WOO ile ilgili olarak PHP ile XML ve cURL kullanımlarına değinmiştim. Bu yazıda ise benzer bir işlemi Node.js ile yeniden gerçekleştireceğim.

AA

Node.js

En temel ifade ile, Node.js için açık kaynaklı geliştirilen ve sunucu tarafında çalışan bir çalıştırma ortamı ifadesi kullanılabilir. Daha detaylı bilgi almak için Node.js ile ilgili yayınlanmış Node.js Nedir? başlıklı yazıma göz atabilirsiniz. Gelelim uygulamamıza.

Node.js ve XML

Node.js veri iletiminde JSON formatını temel alır. Ancak, kimi uygulamalar servisler çeiştili nedenlerden ötürü farklı formatlarla iletişime ihtiyaç duyabilmektedirler. Bu formatlardan biri de elbette XML. Peki, Node.js ile XML dosya işlemlerini nasıl yapabiliriz?

Bildiğimiz üzere, Node.js dünyası modüller üzerine kurulu. Her paket bir amaç doğrultusunda görevler gerçekletiren modül veya modüller yığını. Dolayısıyla ihtiyacımız olan çözümü de modüller arasında aramamız gerekiyor. Modüllerin aranması ve indirilmesi sürecinde de paket yöneticilerine ihtiyaç duyuyoruz. npm bunlardan biri.

npm üzerinde XML ile ilgili1 hızlı bir arama yaptığımızda ~3000 civarında bir sonuca ulaşmaktayız. Popülerlik ve kalite değerlendirmeleri üzerinden filtreleme yaparak kapsamımızı biraz daha daraltabiliriz2.

Node.js İle XML dosyasını JSON'a çevirmek

Örnek işlemde kullanacağımız paketimiz xml2js3. Yaptığı işlem XML dosyalarını JavaScript nesnesine dönüştürmek.

Öncelikle bir XML kaynağına ihtiyacımız var. PHP örneğinde Ideasoft web siteleri tarafından oluşturulan bir XML dosyasını temel almıştık. Bu yazıda ise yine sıklıkla karşılaştığım XML kaynaklarından biri olan haydigiytoptan web sitesi tarafından oluşturulan ve tanımların attribute2 olarak tutulduğu bir örneği kullanacağım.

XML dosyamızın yapısı aşağıda yer almakta. Dosyanın adına da text.xml diyelim.

<?xml version="1.0" encoding="utf-8"?>
  <Products>
    <Product Id="" ModelCode="" Sku="" Gtin="" Name="" ShortDescription="" FullDescription="" Currency="" StockQuantity="" OldPrice="" Price="" Weight="" Price1="" Price2="" Price3="" Price4="" Price5="" Tax="">
    <Categories>
      <Category Path="" DisplayOrder="" />
    </Categories>
    <Manufacturers>
      <Manufacturer Name="" DisplayOrder="" /></Manufacturers>
      <Pictures>
        <Picture Path="" />
      </Pictures>
      <Combinations>
        <Combination Id="" Sku="" Gtin="" StockQuantity="">
        <Attributes>
          <Attribute Name="" Value="" />
        </Attributes>
      </Combination>
    </Combinations>
    <Specifications>
      <Specification Name="" Value="" DisplayOrder="" />
    </Specifications>
    <SameProducts>
      <SameProduct Id="" DisplayOrder="" />
    </SameProducts>
  </Product>
</Products>

Node.js İle XML – JSON İşlemleri

İşlemleri bir sunucu üzerinden gerçekleştireceğim. Bu amaçla DigitalOcean komut satırı uygulaması doctl ile bir Node.js droplet oluşturuyorum.

doctl compute ssh-key list
doctl compute droplet create nodexml --size s-1vcpu-1gb --image sharklabs-nodejsquickstart-18-04 --region sfo2 --ssh-keys <ssh-key-id|name|fingerprint>
doctl compute droplet list --format "ID,Name,PublicIPv4"

Kurulumun tamamlanmasının ardından SSH gerçekleştirerek npm ya da yarn ile paket kurulumu ve kodlama aşamasına geçebilirim.

Bu aşamada doctl üzerinden devam edebileceğiniz gibi SSH isteğini doğrudan da yürütebilirsiniz.

doctl compute ssh <droplet-id>
# ya da
ssh kullanici-adi@ip-adresi

Buraya kadarki tüm aşama bir uzak sunucuda çalışmak istediğinizde takip etmeniz gereken bölümdü. Ancak, localhost üzerinde işlemler gerçekleştirmek isterseniz ve/veya SSH bağlantısı gerçekleştirmişseniz yapmanız gereken node.js kurulumunuzu sorgulamak.

node -v

İlgili sürüm bilgisini almış isek modül kurulumuna geçebiliriz. Aksi durumda node.js indirme ve/veya yapılandırma işleminin gerçekleştirilmesi gerekecektir. Bu konu ile ilgili olarak Node.js Nedir? başlıklı yazımı incelemenizi öneririm.

Kurulumumuz da tamam olduğuna göre projemizi (ben xml2json adını tercih ettim, siz farklı bir isim ile devam edebilirsiniz) oluşturup, xml2js3 paketini indirebiliriz.

mkdir xml2json && cd xml2json
npm init -y
npm install xml2js
# ya da
yarn add xml2js express

Şimdi projemizin detaylarına geçebiliriz4. En temel işlemle başlayalım ve elimizdeki bir XML dosyasını okuyalım.

const xml2js = require('xml2js');
const fs = require('fs');
const express = require('express');

const parser = new xml2js.Parser();
const app = express();
const PORT = process.env.PORT || 3000;
const XML_file = './test.xml';

let data = fs.readFileSync(XML_file, 'utf8');
let JSON_result = '';

parser.parseString(data, (err, result) => {
  if (!err) {
    console.log('JSON is ready.');
    JSON_result = result;
  } else {
    console.log(err);
  }
});

app.get('/', (req, res) => {
  res.format({
    json: () => {
      res.send(JSON_result.Products);
    }
  });
});

app.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

Yukarıdaki kod en temel şekilde ifade etmek gerekirse, ilk olarak fs.readFileSync ile dosya içeriğini data değişkenine atamakta. Ardından, parser.parseString ile data içeriğini -eğer hata dönmezse- JSON_result içeriğine göndermekteyiz.

Bir sonraki aşamada ise Express.js ile URL üzerinden alınan GET isteğine JSON çıktısını göndermekteyiz.

Şimdi, aynı işlemi bir URL üzerinden edindiğimiz XML dosyası için gerçekleştirelim. Bu defa modüllerimizin arasına http5 6 / https7 8 paketini de dahil etmemiz gerekiyor.

const xml2js = require('xml2js');
const https = require('https'); // ya da require("http")
const express = require('express');

const parser = new xml2js.Parser();
const app = express();
const PORT = process.env.PORT || 3000;
const XML_url = 'https://alanadi.com/test.xml';

parser.on('error', (err) => {
  console.log('Parser error', err);
});

let data = '';
let JSON_result = '';

// ya da https.get("https://...);
console.log('Checking url...');
https.get(XML_url, (res) => {
  if (res.statusCode >= 200 && res.statusCode < 400) {
    console.log('XML is parsing...');
    res.on('data', (xmldata) => {
      data += xmldata.toString();
    });
    res.on('end', () => {
      //console.log('data', data);
      parser.parseString(data, (err, result) => {
        if (!err) {
          console.log('JSON is ready.');
          JSON_result = result;
        } else {
          console.log(err);
        }
      });
    });
  }
});

app.get('/', (req, res) => {
  res.format({
    json: () => {
      res.send(JSON_result.Products);
    }
  });
});

app.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

Bir önceki kodumuzdan farklı olarak https.get ile dosyamızı ediniyor ve içeiriğini JSON_result değişkenine atıyoruz. Bu işlem web sunucumuza herhangi bir istek gerçekleştirilmeden önce tamamlanıyor. Dilerseniz bu işlemi Express.js ile belirli bir URI görüntülendiğinde gerçekleşecek şekilde de düzenleyebilirsiniz.

Elbette yukarıdaki örneklerde JSON çıktısının görüntülenebilmesi için farklı bir uç nokta tanımlanabilir, HTML dosyası olarak içerik listelenebilir ya da ara uygulamalar ile çeşitli kontroller ve müdahaleler gerçekleştirilebilir. Diğer yandan, Express.js aracılığıyla JSON çıktısı WooCommerce ya da PIM gibi hedef(ler)e de iletilebilir.

Bir başka örnekte de fast-xml-parser9 modülünü kullanarak XML2WOO eklentisinin gerçekleştirdiği işlemi nasıl bir web uygulaması üzerinden gerçekleştirebileceğimize değineceğim.

İleri Okumalar