source: trunk/Packages/Common/UXMLUtils.pas

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