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.