XML Ayırma - ÇÖZÜLDÜ

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
akissoftware
Üye
Mesajlar: 118
Kayıt: 17 Ağu 2010 09:08

XML Ayırma - ÇÖZÜLDÜ

Mesaj gönderen akissoftware »

Arkadaşlar herkese merhaba;
Bir programda şöyle bir verim var.

Kod: Tümünü seç

<?xml version="1.0" encoding="us-ascii"?><Message AccountID="0028" MsgNum="195"><Event EventCode="1602"></Event></Message>
Bu veri uzunluğu sabit değil. Uzayıp kısalabiliyor. O yüzden satır parçalama ile yapamıyorum. Amacım şu;

Veri içindeki AccountID ve MsgNum (Yani 0028 ve 195) değerlerini almam lazım. Bunu en basit şekilde nasıl yapabilirim ?
En son akissoftware tarafından 22 Tem 2017 08:57 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: XML Ayırma

Mesaj gönderen sabanakman »

İyi günler. XMLDocument bileşeni ile xml verilerini ve özelliklerini düğümlerden çözebilirsiniz. Burada 3 düğüm var ve bunlardan Message isimli düğümün AccountID (değerini değil) özelliğini elde etmek istiyorsunuz. Bunun için aşağıdaki örneği inceleyebilirsiniz. İyi çalışmalar.

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
var XMLNode:IXMLNode;
begin
  XMLDocument1.XML.Text:='<?xml version="1.0" encoding="us-ascii"?><Message AccountID="0028" MsgNum="195"><Event EventCode="1602"></Event></Message>';
  //veya XMLDocument1.XML.LoadFromFile(...xml dosya adı...);
  XMLDocument1.Active:=True;

  XMLNode:=XMLDocument1.ChildNodes['Message'];
  Caption:=XMLNode.Attributes['AccountID'];
end;
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
akissoftware
Üye
Mesajlar: 118
Kayıt: 17 Ağu 2010 09:08

Re: XML Ayırma

Mesaj gönderen akissoftware »

Hocam gereken cevabı aldım ve ayarı yaptım. AccountID ve MsgNum değerlerini aldım. Fakat EventCode değerini alamadım. Yalnız tek üst düzey değere izin veriliyor diye hata veriyor :S

Ellerinize sağlık teşekkürler
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: XML Ayırma

Mesaj gönderen ertank »

Merhaba,

Gönderdiğiniz XML bilgisi formatını düzelttikten sonra aşağıdaki gibi olmaktadır.

Kod: Tümünü seç

<?xml version="1.0" encoding="UTF-8"?>
<Message AccountID="0028" MsgNum="195">
    <Event EventCode="1602" />
</Message>
Kaynak: http://www.freeformatter.com

Bu hali ile bakıldığı zaman EventCode değerini okumak için Message->EventCode şeklinde bir kademe daha içeriye giderek okuma yapmak gerekir. Aşağıdaki kod örneği verilen örnek içindeki tüm bilgileri TMemo bileşeni içine yazmaktadır.

Kod: Tümünü seç

procedure TForm2.Button2Click(Sender: TObject);
var
  XMLNode: IXMLNode;
begin
  XMLDocument1.XML.Text := '<?xml version="1.0" encoding="us-ascii"?><Message AccountID="0028" MsgNum="195"><Event EventCode="1602"></Event></Message>';
  XMLDocument1.Active := True;

  XMLNode := XMLDocument1.ChildNodes['Message'];
  Memo1.Lines.Add('AccountID: ' + XMLNode.Attributes['AccountID']);
  Memo1.Lines.Add('MsgNum: ' + XMLNode.Attributes['MsgNum']);
  // Bir kademe daha içeriye giriyoruz.
  XMLNode := XMLNode.ChildNodes['Event'];
  Memo1.Lines.Add('EventCode: ' + XMLNode.Attributes['EventCode']);
end;
NOT: Form üzerine bir adet TXmlDocument bileşeni eklendiği zaman XML ile gerekli kullanılması gereken tüm uniteler otomatik olarak uses kısmına eklenecektir.

Yukarıdaki kodun TMemo içindeki kaydı aşağıdaki gibi olmaktadır:

Kod: Tümünü seç

AccountID: 0028
MsgNum: 195
EventCode: 1602
akissoftware
Üye
Mesajlar: 118
Kayıt: 17 Ağu 2010 09:08

Re: XML Ayırma

Mesaj gönderen akissoftware »

Hocam senden ALLAH razı olsun. Gerçekten de tam istediğim bir kod oldu.
Ufak tefek yerler var onları da halledersem tamamdır. Herkes için çok teşekkürler
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: XML Ayırma

Mesaj gönderen ertank »

Merhaba,

Öncelikle sorularınızı sorduğunuzda problemi birebir yansıtmanızda fayda var. Zira şu durumda verilen örnekler sorununuzu çözmenize yardımcı olmadı. İkinci olarak gönderdiğiniz mesaja istinaden. Sorularınızı foruma direk yöneltmeniz ileride aynı problem ile karşılaşacaklara da yardımcı olacaktır.

Kullandığınız Delphi sürümünü belirtmemişsiniz. Aşağıdaki kod örneği Delphi 10.2 ile çalışmaktadır. Siz Delphi 7 gibi bir sürüm kullanıyor iseniz uyarlama yapmak gerekebilir.

Bu açıklamalardan sonra. Gönderdiğiniz yeni xml formatının daha okunaklı hale getirilmiş şekli aşağıdaki gibi olmaktadır:

Kod: Tümünü seç

<?xml version="1.0" encoding="UTF-8"?>
<Message AccountID="0007" MsgNum="283">
    <Event EventKey="0007183401000317" EventCode="3401">
        <Device DeviceID="031" />
        <DateTime>19.07.2017 17:05:33</DateTime>
    </Event>
</Message>
Burada Device ve DateTime bilgileri Event'a göre bir kademe daha içeride oluyor. Ayrıca Event içine bir kademe girdikten sonra tek bir node bilgisine erişebildiğimiz için "Event" XMLNode pozisyonunu saklamamız gerekecek.

DateTime ise bir Attribute içermiyor. Bilgi direk kendi üzerinde. Bu sebeple DateTime bilgisini farklı şekilde okumamız gerekli.

Son olarak, okunan DateTime bilgisi spesifik bir format kullanılarak gönderilmiş. Bu formata uygun olarak TDateTime türüne çevirmemiz gerekir ki program içinde rahat bir şekilde kullanabilelim.

Bu anlatılanları önceki örnek ile birleştirerek aşağıdaki gibi bir kod yazmamız mümkün olabilir:

Kod: Tümünü seç

uses
  DateUtils;

procedure TForm2.Button1Click(Sender: TObject);
var
  XMLNode: IXMLNode;
  // Aynı seviyede iki farklı XMLNode okumak gerekli. Pozisyonumuzu korumak için aşağıdaki değişkeni kullanacağız.
  XMLEventNode: IXMLNode;
  // Aşağıdaki iki değişken XML içindeki Tarih değerini TDateTime olarak dönüştürmek için
  Zaman: TDateTime;
  Format: TFormatSettings;
begin
  XMLDocument1.Active := False;
  XMLDocument1.XML.Text := '<?xml version="1.0" encoding="us-ascii"?><Message AccountID="0007" MsgNum="283"><Event EventKey="0007183401000317" EventCode="3401"><Device DeviceID="031" /><DateTime>19.07.2017 17:05:33</DateTime></Event></Message>';
  XMLDocument1.Active := True;

  XMLNode := XMLDocument1.ChildNodes['Message'];
  Memo1.Lines.Add('AccountID: ' + XMLNode.Attributes['AccountID']);
  Memo1.Lines.Add('MsgNum: ' + XMLNode.Attributes['MsgNum']);
  // Bir kademe daha içeriye giriyoruz. Yeni kademe: 2
  XMLEventNode := XMLNode.ChildNodes['Event'];
  Memo1.Lines.Add('EventKey: ' + XMLEventNode.Attributes['EventKey']);
  Memo1.Lines.Add('EventCode: ' + XMLEventNode.Attributes['EventCode']);
  // Bir kademe daha içeriye giriyoruz. Yeni kademe: 3
  XMLNode := XMLEventNode.ChildNodes['Device'];
  Memo1.Lines.Add('DeviceID: ' + XMLNode.Attributes['DeviceID']);
  XMLNode := XMLEventNode.ChildNodes['DateTime'];
  // DateTime bir attribute içermiyor. Direk kendisi bir değer içeriyor.
  // Bunun için Attribute değil NodeValue kullanmalıyız.
  Memo1.Lines.Add('DateTime: ' + XMLNode.NodeValue);

  // Tarih formatı bilgisayardan bilgisayara değişebilir.
  // Bunun için string -> DateTime dönüşümü yaparken XML dosya içindeki formatı belirtmek gerekir.
  Format.ShortDateFormat := 'dd.mm.yyyy';
  Format.ShortTimeFormat := 'hh:nn:ss';
  Format.DateSeparator := '.';
  Format.TimeSeparator := ':';
  try
    Zaman := StrToDateTime(XMLNode.NodeValue, Format);
  except
    // Tarih formatı hatalı. Dosya içeriği incelenerek bu durumdan emin olunması gerekli.
    // Eğer gerçekten tarih formatı değişmiş ise XML dosyasını aldığımız yer ile görüşerek
    // Formatın bir hata sonucu mu değiştiğini yoksa kalıcı mı olduğunu öğrenip kendi kodumuzu
    // yeni formata göre uyarlamalıyız.
    raise;

    // Yukarıda StrToDateTimeDef() fonksiyonu da kullanılabilir idi. Ancak bu fonksiyon kullanıldığı
    // zaman karşı karafın format değiştirdiğini anlamak mümkün olmayacaktır. Dönüşüm gerçekleşemediği
    // takdirde "Default" olarak verilen tarih değerini bize geri çevirecektir.
  end;
  // Elimizde TDateTime türünde bir değişken olduktan sonra bunu istediğimiz gibi kullanabiliriz.
  Memo1.Lines.Add('Zaman: ' + FormatDateTime('yyyy-mm-dd hh:nn:ss', Zaman));
end;
Not: Bütün string okumaları direk olarak yapıldı. Yani herhangi bir UTF-8'den string'e dönüşüm yapılmadı. Bu dönüşümü zaten sizin yapmış olduğunuzu varsayıyoruz burada. İleride string değerler içinde Türkçe'ye özel karakterler olur ve bu karakterleri düzgün okuyamaz iseniz UTF8ToString() fonksiyonunu araştırıp kullanmanız gerekecektir. Ya da dosyadan okuma yapıyor iseniz UTF8 dosyadan okuma konusunda araştırma yapmanız gerekecektir.
akissoftware
Üye
Mesajlar: 118
Kayıt: 17 Ağu 2010 09:08

Re: XML Ayırma

Mesaj gönderen akissoftware »

Haklısınız.. İnşallah başka arkadaşlarında işine yarar. Detaylı cevabınız için teşekkür ediyorum.

Sizlere çok çok teşekkür ediyorum. Tamamen çalışıyor Hemde delphi 2007 de... :bravo:

Zaman ayırıp yazdığınız için teşekkür ederim
Cevapla