source: trunk/Packages/Common/XML.pas

Last change on this file was 85, checked in by chronos, 7 months ago
  • Modified: Updated Common package.
File size: 8.5 KB
Line 
1unit XML;
2
3interface
4
5uses
6 {$IFDEF WINDOWS}Windows,{$ENDIF}
7 Classes, SysUtils, DateUtils, DOM, xmlread;
8
9function XMLTimeToDateTime(XMLDateTime: string): TDateTime;
10function DateTimeToXMLTime(Value: TDateTime; ApplyLocalBias: Boolean = True): string;
11procedure WriteInteger(Node: TDOMNode; Name: string; Value: Integer);
12procedure WriteInt64(Node: TDOMNode; Name: string; Value: Int64);
13procedure WriteBoolean(Node: TDOMNode; Name: string; Value: Boolean);
14procedure WriteString(Node: TDOMNode; Name: string; Value: string);
15procedure WriteDateTime(Node: TDOMNode; Name: string; Value: TDateTime);
16procedure WriteDouble(Node: TDOMNode; Name: string; Value: Double);
17function ReadInteger(Node: TDOMNode; Name: string; DefaultValue: Integer): Integer;
18function ReadInt64(Node: TDOMNode; Name: string; DefaultValue: Int64): Int64;
19function ReadBoolean(Node: TDOMNode; Name: string; DefaultValue: Boolean): Boolean;
20function ReadString(Node: TDOMNode; Name: string; DefaultValue: string): string;
21function ReadDateTime(Node: TDOMNode; Name: string; DefaultValue: TDateTime): TDateTime;
22function ReadDouble(Node: TDOMNode; Name: string; DefaultValue: Double): Double;
23procedure ReadXMLFileParser(out Doc: TXMLDocument; FileName: string);
24
25
26implementation
27
28function ReadDouble(Node: TDOMNode; Name: string; DefaultValue: Double): Double;
29var
30 NewNode: TDOMNode;
31begin
32 Result := DefaultValue;
33 NewNode := Node.FindNode(DOMString(Name));
34 if Assigned(NewNode) then
35 Result := StrToFloat(string(NewNode.TextContent));
36end;
37
38procedure ReadXMLFileParser(out Doc: TXMLDocument; FileName: string);
39var
40 Parser: TDOMParser;
41 Src: TXMLInputSource;
42 InFile: TFileStream;
43begin
44 try
45 InFile := TFileStream.Create(FileName, fmOpenRead);
46 Src := TXMLInputSource.Create(InFile);
47 Parser := TDOMParser.Create;
48 Parser.Options.PreserveWhitespace := True;
49 Parser.Parse(Src, Doc);
50 finally
51 Src.Free;
52 Parser.Free;
53 InFile.Free;
54 end;
55end;
56
57function GetTimeZoneBias: Integer;
58{$IFDEF WINDOWS}
59var
60 TimeZoneInfo: TTimeZoneInformation;
61begin
62 {$push}{$warn 5057 off}
63 case GetTimeZoneInformation(TimeZoneInfo) of
64 TIME_ZONE_ID_STANDARD: Result := TimeZoneInfo.Bias + TimeZoneInfo.StandardBias;
65 TIME_ZONE_ID_DAYLIGHT: Result := TimeZoneInfo.Bias + TimeZoneInfo.DaylightBias;
66 else
67 Result := 0;
68 end;
69 {$pop}
70end;
71{$ELSE}
72begin
73 Result := 0;
74end;
75{$ENDIF}
76
77function LeftCutString(var Source: string; out Output: string; Delimiter: string; Allowed: string = ''): Boolean;
78var
79 I: Integer;
80 Matched: Boolean;
81begin
82 I := 1;
83 Matched := True;
84 while (I < Length(Source)) and Matched do begin
85 Matched := True;
86 if (Source[I] = Delimiter) then Matched := False;
87 //for J := 1 to Length(Allowed) do
88 // if Source[I] = Allowed[J] then Matched := True;
89 if Matched then Inc(I);
90 end;
91 if (Delimiter = Copy(Source, I, Length(Delimiter))) or (I = Length(Source)) then begin
92 Output := Copy(Source, 1, I - 1);
93 Delete(Source, 1, Length(Output) + Length(Delimiter));
94 Result := True;
95 end else begin
96 Output := '';
97 Result := False;
98 end;
99end;
100
101function XMLTimeToDateTime(XMLDateTime: string): TDateTime;
102var
103 Part: string;
104 Year: Integer;
105 Month: Integer;
106 Day: Integer;
107 Hour: Integer;
108 Minute: Integer;
109 Second: Integer;
110 SecondFraction: Double;
111 Millisecond: Integer;
112begin
113 if LeftCutString(XMLDateTime, Part, '-') then
114 Year := StrToInt(Part);
115 if LeftCutString(XMLDateTime, Part, '-') then
116 Month := StrToInt(Part);
117 if Pos('T', XMLDateTime) > 0 then begin
118 if LeftCutString(XMLDateTime, Part, 'T') then
119 Day := StrToInt(Part);
120 if LeftCutString(XMLDateTime, Part, ':') then
121 Hour := StrToInt(Part);
122 if LeftCutString(XMLDateTime, Part, ':') then
123 Minute := StrToInt(Part);
124 if Pos('.', XMLDateTime) > 0 then begin
125 if LeftCutString(XMLDateTime, Part, '.') then
126 Second := StrToInt(Part);
127 if Pos('+', XMLDateTime) > 0 then
128 LeftCutString(XMLDateTime, Part, '+') else
129 if Pos('-', XMLDateTime) > 0 then
130 LeftCutString(XMLDateTime, Part, '-') else
131 if Pos('Z', XMLDateTime) > 0 then
132 LeftCutString(XMLDateTime, Part, 'Z');
133 SecondFraction := StrToFloat('0' + DefaultFormatSettings.DecimalSeparator + Part);
134 Millisecond := Trunc(SecondFraction * 1000);
135 end else begin
136 if Pos('+', XMLDateTime) > 0 then
137 LeftCutString(XMLDateTime, Part, '+') else
138 if Pos('-', XMLDateTime) > 0 then
139 LeftCutString(XMLDateTime, Part, '-') else
140 if Pos('Z', XMLDateTime) > 0 then
141 LeftCutString(XMLDateTime, Part, 'Z');
142 Second := StrToInt(Part);
143 Millisecond := 0;
144 end;
145 end else begin
146 Day := StrToInt(XMLDateTime);
147 end;
148 Result := EncodeDateTime(Year, Month, Day, Hour, Minute, Second, Millisecond);
149 // TODO: Correct time by zone bias
150end;
151
152function DateTimeToXMLTime(Value: TDateTime; ApplyLocalBias: Boolean = True): string;
153const
154 Neg: array[Boolean] of string = ('+', '-');
155var
156 Bias: Integer;
157begin
158 Result := FormatDateTime('yyyy''-''mm''-''dd''T''hh'':''nn'':''ss''.''zzz', Value); { Do not localize }
159 Bias := GetTimeZoneBias;
160 if (Bias <> 0) and ApplyLocalBias then
161 begin
162 Result := Format('%s%s%.2d:%.2d', [Result, Neg[Bias > 0], { Do not localize }
163 Abs(Bias) div MinsPerHour,
164 Abs(Bias) mod MinsPerHour]);
165 end else
166 Result := Result + 'Z'; { Do not localize }
167end;
168
169procedure WriteInteger(Node: TDOMNode; Name: string; Value: Integer);
170var
171 NewNode: TDOMNode;
172begin
173 NewNode := Node.OwnerDocument.CreateElement(DOMString(Name));
174 NewNode.TextContent := DOMString(IntToStr(Value));
175 Node.AppendChild(NewNode);
176end;
177
178procedure WriteInt64(Node: TDOMNode; Name: string; Value: Int64);
179var
180 NewNode: TDOMNode;
181begin
182 NewNode := Node.OwnerDocument.CreateElement(DOMString(Name));
183 NewNode.TextContent := DOMString(IntToStr(Value));
184 Node.AppendChild(NewNode);
185end;
186
187procedure WriteBoolean(Node: TDOMNode; Name: string; Value: Boolean);
188var
189 NewNode: TDOMNode;
190begin
191 NewNode := Node.OwnerDocument.CreateElement(DOMString(Name));
192 NewNode.TextContent := DOMString(BoolToStr(Value));
193 Node.AppendChild(NewNode);
194end;
195
196procedure WriteString(Node: TDOMNode; Name: string; Value: string);
197var
198 NewNode: TDOMNode;
199begin
200 NewNode := Node.OwnerDocument.CreateElement(DOMString(Name));
201 NewNode.TextContent := DOMString(Value);
202 Node.AppendChild(NewNode);
203end;
204
205procedure WriteDateTime(Node: TDOMNode; Name: string; Value: TDateTime);
206var
207 NewNode: TDOMNode;
208begin
209 NewNode := Node.OwnerDocument.CreateElement(DOMString(Name));
210 NewNode.TextContent := DOMString(DateTimeToXMLTime(Value));
211 Node.AppendChild(NewNode);
212end;
213
214procedure WriteDouble(Node: TDOMNode; Name: string; Value: Double);
215var
216 NewNode: TDOMNode;
217begin
218 NewNode := Node.OwnerDocument.CreateElement(DOMString(Name));
219 NewNode.TextContent := DOMString(FloatToStr(Value));
220 Node.AppendChild(NewNode);
221end;
222
223function ReadInteger(Node: TDOMNode; Name: string; DefaultValue: Integer): Integer;
224var
225 NewNode: TDOMNode;
226begin
227 Result := DefaultValue;
228 NewNode := Node.FindNode(DOMString(Name));
229 if Assigned(NewNode) then
230 Result := StrToInt(string(NewNode.TextContent));
231end;
232
233function ReadInt64(Node: TDOMNode; Name: string; DefaultValue: Int64): Int64;
234var
235 NewNode: TDOMNode;
236begin
237 Result := DefaultValue;
238 NewNode := Node.FindNode(DOMString(Name));
239 if Assigned(NewNode) then
240 Result := StrToInt64(string(NewNode.TextContent));
241end;
242
243function ReadBoolean(Node: TDOMNode; Name: string; DefaultValue: Boolean): Boolean;
244var
245 NewNode: TDOMNode;
246begin
247 Result := DefaultValue;
248 NewNode := Node.FindNode(DOMString(Name));
249 if Assigned(NewNode) then
250 Result := StrToBool(string(NewNode.TextContent));
251end;
252
253function ReadString(Node: TDOMNode; Name: string; DefaultValue: string): string;
254var
255 NewNode: TDOMNode;
256begin
257 Result := DefaultValue;
258 NewNode := Node.FindNode(DOMString(Name));
259 if Assigned(NewNode) then
260 Result := string(NewNode.TextContent);
261end;
262
263function ReadDateTime(Node: TDOMNode; Name: string; DefaultValue: TDateTime
264 ): TDateTime;
265var
266 NewNode: TDOMNode;
267begin
268 Result := DefaultValue;
269 NewNode := Node.FindNode(DOMString(Name));
270 if Assigned(NewNode) then
271 Result := XMLTimeToDateTime(string(NewNode.TextContent));
272end;
273
274end.
Note: See TracBrowser for help on using the repository browser.