21 Ocak 2021 Perşembe

Parser Çalışmalarım - XML Yapısı

Giriş
Bir kaç defa, XML'de tanımlı mesaj yapılarını okuyup bunları parse edebilen kodlarla uğraşmam gerekti. Bazı şeyleri not almak istedim

1. Birbirinden çok farklı XML yapılarını işleyebilecek jenerik bir kod yazmak çok zor bir şey. Var olan yapıya uymayan bir XML gelince bir sürü adaptor yazmak gerekiyor. Bu kadar uğraşa değmeyebilir.

İki Tane XML Lazım
Genellikle iki tane XML gerekiyor. Bu XML dosyalarına farkı farklı isimler verilebilir. Ben kısaca şöyle diyeceğim

1. Record Definition XML
2. Element Definition XML

Record Definition XML
Parse edilecek tüm mesajları içerir. Çoğu protokolde, Record içinde Record var. En azından mesajlarda header bulunuyor.

Element Definition XML
Record içindeki alanlar genellikle bir çok farklı yerde kullanılıyor. Bu yüzden element veya field diye düşünülebilecek bu yapıları farklı bir XML içinde tanımlamak gerekiyor.
1. Her Element 'in bir tane tekil key değeri bulunuyor. Buna identifier diyelim.

Örnek
Sadece 2 tane element 'ten ibaret çok basit bir record
<record id="foo">
  <field id="timeIndicator"/>
 <field id="statusIndicator"/>
</record>
Element yapısı şöyle. Burada field'ın her bir değerinin ne anlama geldiği gösteriliyor.
<element id="timeIndicator" length="2">
  <item code="0" value="No Time Indicator">
  <item code="1" value="Time Indicator">
</element>
XML okunur ve XmlDefinition ve ondan katılan sınıflar yaratılır. Bu sınıflar RecordDefinition, FieldDefinition vs. gibi şeyler. Definition sınıflar sadece XML'deki veriyi bilirler. Yani metadata.

Metadata'yı sarmalayan sınıflar lazım. Bunlar Record, Field gibi sınıflar.  

Record nesnesi kabaca şöyle. Her field kendi içindeki definition nesnesine bakarak stream'den ne kadar veri okuyacağını biliyor. 
public class Record {
  List<Field> fields;

  public boolean parse(Stream stream){
    //Field'ları dolaş ve stream'den okunan değerleri ata
  }
}
Örnek - Açmalı Kapamalı Alanlar
Bu yapılarda F1 gibi bir alanın değerine bakılır. 
- Eğer F1 = 0 ise, F2 ve F3 alanlar geçerlidir. 
- F1 farklı bir değere sahipse, F4 alanı geçerlidir. Yani kod olarak düşünürsek if/else yapısına benziyor

Birinci problem bu yapıyı XML olarak ifade edebilmek. İkinci problem ise bu yapıyı parse edebilecek jenerik kodu yazabilmek.

XML şöyle olabilir. Bu aslında çok basit bir örnek. Çok daha karmaşık şeyler düşünülebilir.
<record id="foo">
  <field id="timeIndicator"/>
  <field id="statusIndicator"/>
  <structureswitch id="indicatorSwitch">
    <when>
      <case value="1"/>
      <field id="voiceIndicator"/>
    </when>
    <when>
      <case value="2"/>
        <field id="smsIndicator"/>
    </when>
    <otherwise>
      <field id="emailIndicator"/>
    </otherwise>
  </structureswitch>
</record>


Hiç yorum yok:

Yorum Gönder