Develop and Download Open Source Software

Browse CVS Repository

Contents of /gikonavigoeson/gikonavi/GikoXMLDoc.pas

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2.2.3 - (show annotations) (download) (as text)
Fri Oct 8 05:44:52 2004 UTC (19 years, 6 months ago) by yoffy
Branch: stable
Changes since 1.2.2.2: +147 -125 lines
File MIME type: text/x-pascal
b49 、ヒ・゙。シ・ク。」

1 unit GikoXMLDoc;
2
3 {
4 XMLIntf, XMLDoc 縺ゅ◆繧翫?繧ッ繝ュ繝シ繝ウ
5 Delphi 6 Personal 逕ィ
6 }
7 interface
8
9 //==================================================
10 uses
11 //==================================================
12
13 Classes, SysUtils, Windows,
14 YofUtils;
15
16 //==================================================
17 type
18 //==================================================
19
20 // 繧上¢繧上°繧峨★菴懊▲縺ヲ繧九°繧峨ヰ繧ー縺?繧峨¢縺九b
21 XMLDictionary = Record
22 Name : string;
23 Value : string;
24 end;
25
26 IXMLNode = class
27 private
28 FNodeName : string;
29 FCapacity : Integer;
30 FCount : Integer;
31 FAttributeCount : Integer;
32 FChildNodes : IXMLNode;
33 FNodes : array of IXMLNode;
34 FAttributes : array of XMLDictionary;
35 function GetAttribute( const Name : string ) : string;
36 function GetNode( Index : Integer ) : IXMLNode;
37 public
38 constructor Create;
39 destructor Destroy; override;
40
41 property NodeName : string read FNodeName write FNodeName;
42 property Attributes[ const Name : string ] : string read GetAttribute;
43 property Node[ Index : Integer ] : IXMLNode read GetNode; default;
44 property ChildNodes : IXMLNode read FChildNodes write FChildNodes;
45 property Count : Integer read FCount write FCount;
46 procedure Add( node : IXMLNode );
47 procedure AddAttribute( const Name : string; const Value : string );
48 end;
49
50 IXMLDocument = class( IXMLNode )
51 private
52 function GetDocumentElement() : IXMLNode;
53 public
54 property DocumentElement : IXMLNode read GetDocumentElement;
55 end;
56
57 function XMLCloseCheck(
58 var p : PChar;
59 const tail : PChar;
60 var node : IXMLNode;
61 out tag : string;
62 out closed : boolean // 蜻シ縺ウ蜃コ縺励◆繝ォ繝シ繝√Φ縺 node 繧帝哩縺倥k縺ケ縺阪↑繧 true
63 ) : boolean; // ch 繧偵%縺ョ繝ォ繝シ繝√Φ縺悟?逅?@縺溘↑繧 true
64
65 function XMLReadNode(
66 var p : PChar;
67 const tail : PChar;
68 var node : IXMLNode
69 ) : string; // node 莉・螟悶?繝弱?繝峨′髢峨§繧峨l縺溷?エ蜷医?繝弱?繝牙錐
70
71 procedure LoadXMLDocument(
72 const fileName : string;
73 var doc : IXMLDocument
74 );
75
76 //==================================================
77 const
78 //==================================================
79 kXMLWhite : TSysCharSet = [#0..#$20];
80 kXMLNodeNameStop : TSysCharSet = [#0..#$20, '/', '>'];
81 kXMLAttributeNameStop : TSysCharSet = [#0..#$20, '=', '/', '>'];
82 kXMLDQuote : TSysCharSet = ['"'];
83 kXMLTagStart : TSysCharSet = ['<'];
84 kXMLTagEnd : TSysCharSet = ['>'];
85 kXMLKanji : TSysCharSet = [#$81..#$9f, #$E0..#$fc];
86
87 //==================================================
88 implementation
89 //==================================================
90
91 // Constructor
92 constructor IXMLNode.Create;
93 begin
94
95 inherited;
96
97 FCapacity := 0;
98 FCount := 0;
99
100 end;
101
102 // Destructor
103 destructor IXMLNode.Destroy;
104 var
105 i : Integer;
106 begin
107
108 for i := FCount - 1 downto 0 do
109 FNodes[ i ].Free;
110 FChildNodes.Free;
111
112 inherited;
113
114 end;
115
116 function IXMLNode.GetAttribute( const Name : string ) : string;
117 var
118 i : Integer;
119 begin
120
121 i := 0;
122 while i < FAttributeCount do
123 begin
124 if Name = FAttributes[ i ].Name then
125 begin
126 Result := FAttributes[ i ].Value;
127 exit;
128 end;
129
130 Inc( i );
131 end;
132
133 end;
134
135 function IXMLNode.GetNode( Index : Integer ) : IXMLNode;
136 begin
137
138 Result := FNodes[ Index ];
139
140 end;
141
142 procedure IXMLNode.Add( node : IXMLNode );
143 begin
144
145 Inc( FCount );
146 if FCount > FCapacity then begin
147 FCapacity := FCapacity + (FCapacity shr 2) + 1;
148 SetLength( FNodes, FCapacity );
149 end;
150
151 FNodes[ FCount - 1 ] := node;
152
153 end;
154
155 procedure IXMLNode.AddAttribute(
156 const Name : string;
157 const Value : string
158 );
159 var
160 index : Integer;
161 begin
162
163 index := FAttributeCount;
164 Inc( FAttributeCount );
165 SetLength( FAttributes, FAttributeCount );
166
167 FAttributes[ index ].Name := Name;
168 FAttributes[ index ].Value := Value;
169
170 end;
171
172 function IXMLDocument.GetDocumentElement() : IXMLNode;
173 begin
174
175 Result := FChildNodes[ 0 ];
176
177 end;
178
179 {*!
180 \brief tok 繧呈爾縺?/span>
181 \param p 謗「邏「髢句ァ倶ス咲スョ
182 \param tail 邨ゆコ?ス咲スョ + 1
183 \param tok 謗「縺吶く繝」繝ゥ繧ッ繧ソ
184 \return tok 縺梧怙蛻昴↓隕九▽縺九▲縺滉ス咲スョ
185 *}
186 function AnsiStrTok(
187 p : PChar;
188 const tail : PChar;
189 const tok : TSysCharSet
190 ) : PChar;
191 begin
192
193 while p < tail do
194 begin
195 if p^ in tok then
196 begin
197 Break;
198 end else if p^ in kXMLKanji then
199 p := p + 2
200 else
201 Inc( p );
202 end;
203
204 Result := p;
205
206 end;
207
208 {*!
209 \brief tok 縺ァ縺ッ辟。縺?く繝」繝ゥ繧ッ繧ソ繧呈爾縺?/span>
210 \param p 謗「邏「髢句ァ倶ス咲スョ
211 \param tail 邨ゆコ?ス咲スョ + 1
212 \param tok 謗「縺吶く繝」繝ゥ繧ッ繧ソ
213 \return tok 縺ァ縺ッ縺ェ縺?く繝」繝ゥ繧ッ繧ソ縺梧怙蛻昴↓隕九▽縺九▲縺滉ス咲スョ
214 *}
215 function AnsiStrNonTok(
216 p : PChar;
217 const tail : PChar;
218 const tok : TSysCharSet
219 ) : PChar;
220 begin
221
222 while p < tail do
223 begin
224 if p^ in tok then
225 begin
226 if p^ in kXMLKanji then
227 p := p + 2
228 else
229 Inc( p );
230 end else begin
231 Break;
232 end;
233 end;
234
235 Result := p;
236
237 end;
238
239 function XMLCloseCheck(
240 var p : PChar;
241 const tail : PChar;
242 var node : IXMLNode;
243 out tag : string;
244 out closed : boolean
245 ) : boolean; // ch 繧偵%縺ョ繝ォ繝シ繝√Φ縺悟?逅?@縺溘↑繧 true
246 var
247 found : PChar;
248 begin
249
250 closed := false;
251 Result := false;
252 tag := '';
253
254 case p^ of
255 '>':
256 begin
257 // 髢句ァ九ち繧ー縺ョ譛?蠕後∪縺ァ隱ュ繧薙□
258 Inc( p ); // '>' 鬟帙?縺?/span>
259 Result := true;
260 end;
261
262 '?':
263 begin
264 // <?xml?> 縺ソ縺溘>縺ェ繧?▽縲ゅh縺」縺ヲ辟。隕?/span>
265 p := AnsiStrTok( p, tail, kXMLTagEnd );
266 p := AnsiStrTok( p, tail, kXMLTagStart );
267 Inc( p ); // '<' 鬟帙?縺?/span>
268 p := AnsiStrNonTok( p, tail, kXMLWhite );
269 //closed := true;
270 Result := true;
271 end;
272
273 '/':
274 begin
275 // 繧ソ繧ー蜷阪r隱ュ縺ソ霎シ繧薙〒霑斐☆
276 Inc( p ); // '/' 鬟帙?縺?/span>
277 found := AnsiStrTok( p, tail, kXMLTagEnd );
278 // tag := Copy( p, 0, found - p ); // 菴墓腐縺区ソ?驕?/span>
279 SetLength( tag, found - p );
280 CopyMemory( PChar( tag ), p, found - p );
281
282 p := found + 1; // '>' 鬟帙?縺?/span>
283 closed := true;
284 Result := true;
285 end;
286 end;
287
288 end;
289
290 function XMLReadNode(
291 var p : PChar;
292 const tail : PChar;
293 var node : IXMLNode
294 ) : string; // node 莉・螟悶?繝弱?繝峨′髢峨§繧峨l縺溷?エ蜷医?繝弱?繝牙錐
295 var
296 child : IXMLNode;
297
298 found : PChar;
299 tag : string;
300
301 isClosed : boolean;
302
303 nodeName : string;
304 attributeName : string;
305 attributeValue : string;
306 label
307 NextNode;
308 begin
309 try
310 // node 縺ョ隱ュ縺ソ霎シ縺ソ(1 繝ォ繝シ繝励↓縺、縺 1 繝弱?繝?
311 node.ChildNodes := IXMLNode.Create;
312
313 while p < tail do
314 begin
315 // NodeName 隱ュ縺ソ霎シ縺ソ
316 p := AnsiStrNonTok( p, tail, kXMLWhite );
317
318 while p < tail do
319 begin
320 if XMLCloseCheck( p, tail, node, tag, isClosed ) then
321 begin
322 if isClosed then
323 begin
324 Result := tag;
325 exit;
326 end;
327
328 goto NextNode;
329 end else if p^ = '<' then
330 begin
331 // 譁ー隕上ヮ繝シ繝?/span>
332 Inc( p );
333 child := IXMLNode.Create;
334 tag := XMLReadNode( p, tail, child );
335 node.ChildNodes.Add( child );
336
337 // 繧ソ繧ー縺碁哩縺倥i繧後◆
338 if Length( tag ) > 0 then
339 begin
340 // 閾ェ蛻??繧ゅ?縺九メ繧ァ繝?け縺励※縲?&縺医?隕ェ縺ォ霑斐☆
341 if tag <> node.NodeName then
342 Result := tag;
343 exit;
344 end;
345
346 goto NextNode;
347 end else if p^ in kXMLWhite then
348 begin
349 // NodeName 螳御コ?/span>
350 break;
351 end else begin
352 found := AnsiStrTok( p, tail, kXMLNodeNameStop );
353 SetLength( nodeName, found - p );
354 CopyMemory( PChar( nodeName ), p, found - p );
355 node.NodeName := nodeName;
356
357 p := found;
358 end;
359 end;
360
361 // Attribute 縺ョ隱ュ縺ソ霎シ縺ソ
362 while p < tail do
363 begin
364 // Attribute 縺ョ蜷榊燕繧定ェュ縺ソ霎シ縺ソ
365 attributeName := '';
366 attributeValue := '';
367
368 p := AnsiStrNonTok( p, tail, kXMLWhite );
369
370 while p < tail do
371 begin
372 if XMLCloseCheck( p, tail, node, tag, isClosed ) then
373 begin
374 if isClosed then
375 begin
376 // 繧ソ繧ー縺碁哩縺倥i繧後◆縺ョ縺ァ繝ェ繧ソ繝シ繝ウ
377 // 窶サNodeName 繧帝?夐℃縺励※繧九?縺ァ騾比クュ縺ァ髢峨§縺ヲ繧九%縺ィ縺ォ縺ェ繧九??/span>
378 // 繧医▲縺ヲ迢ャ遶九ヮ繝シ繝峨??/span>
379 exit;
380 end;
381
382 // 谺。縺ョ繝弱?繝峨∈
383 goto NextNode;
384 end else if p^ = '=' then
385 begin
386 // 縺薙%縺九i縺ッ蛟、縺悟ァ九∪繧九?縺ァ蜷榊燕縺ッ邨ゆコ?/span>
387 Inc( p );
388 break;
389 end else if p^ in kXMLWhite then
390 begin
391 // Value 縺悟ュ伜惠縺励↑縺?隕乗?シ螟?縺ョ縺ァ谺。縺ョ繝弱?繝峨∈
392 goto NextNode;
393 end else begin
394 found := AnsiStrTok( p, tail, kXMLAttributeNameStop );
395 SetLength( attributeName, found - p );
396 CopyMemory( PChar( attributeName ), p, found - p );
397
398 p := found;
399 end;
400 end;
401
402 // Attribute 縺ョ蛟、繧定ェュ縺ソ霎シ縺ソ
403 p := AnsiStrNonTok( p, tail, kXMLWhite );
404
405 while p < tail do
406 begin
407 if XMLCloseCheck( p, tail, node, tag, isClosed ) then
408 begin
409 if isClosed then
410 begin
411 if Length( attributeName ) > 0 then
412 // 隕乗?シ螟悶□縺代←縺ュ
413 node.AddAttribute( attributeName, attributeValue );
414
415 // 繧ソ繧ー縺碁哩縺倥i繧後◆縺ョ縺ァ繝ェ繧ソ繝シ繝ウ
416 // 窶サNodeName 繧帝?夐℃縺励※繧九?縺ァ騾比クュ縺ァ髢峨§縺ヲ繧九%縺ィ縺ォ縺ェ繧九??/span>
417 // 繧医▲縺ヲ迢ャ遶九ヮ繝シ繝峨??/span>
418 exit;
419 end;
420
421 // 谺。縺ョ繝弱?繝峨∈
422 goto NextNode;
423 end else if p^ = '"' then
424 begin
425 // 蛟、縺 "" 縺ァ諡ャ繧峨l縺ヲ繧九?縺ァ(縺ヲ縺?≧縺区峡繧峨l縺ヲ縺ェ縺阪c縺?¢縺ェ縺?s縺?縺代←)
426 // 蛟、繧剃ク?諡ャ隱ュ縺ソ霎シ縺ソ
427 Inc( p );
428 found := AnsiStrTok( p, tail, kXMLDQuote );
429 // attributeValue := Copy( p, 0, found - p ); // 菴墓腐縺区ソ?驕?/span>
430 SetLength( attributeValue, found - p );
431 CopyMemory( PChar( attributeValue ), p, found - p );
432
433 node.AddAttribute( attributeName, HtmlDecode( attributeValue ) );
434
435 // 蛟、繧定ェュ縺ソ邨ゅo縺」縺溘?縺ァ邨ゆコ?/span>
436 p := found + 1; // '"' 鬟帙?縺?/span>
437 break;
438 end else if p^ in kXMLWhite then
439 begin
440 // 隕乗?シ螟悶□縺代←縺ュ
441 node.AddAttribute( attributeName, HtmlDecode( attributeValue ) );
442
443 goto NextNode;
444 end else begin
445 // 隕乗?シ螟悶□縺代←荳?蠢懷叙縺」縺ヲ縺翫¥
446 attributeValue := attributeValue + p^;
447
448 if p^ in kXMLKanji then
449 begin
450 attributeValue := attributeValue + (p + 1)^;
451 p := p + 2;
452 end else begin
453 Inc( p );
454 end;
455 end;
456 end;
457 end; // Attribute 縺ョ隱ュ縺ソ霎シ縺ソ
458
459 NextNode:;
460 end; // // node 縺ョ隱ュ縺ソ霎シ縺ソ(1 繝ォ繝シ繝励↓縺、縺 1 繝弱?繝?
461 finally
462 end;
463 end;
464
465 procedure LoadXMLDocument(
466 const fileName : string;
467 var doc : IXMLDocument
468 );
469 type
470 xmlMode = ( xmlHoge );
471 var
472 xmlFile : TMappedFile;
473 p : PChar;
474 begin
475 //Result := IXMLDocument.Create;
476 //doc := IXMLDocument.Create;
477
478 xmlFile := TMappedFile.Create( fileName );
479
480 try
481 p := xmlFile.Memory;
482 XMLReadNode( p, p + xmlFile.Size, IXMLNode( doc ) );
483 //XMLReadNode( xmlFile, IXMLNode( Result ) );
484 finally
485 xmlFile.Free;
486 end;
487
488 //Result := doc;
489
490 end;
491
492 end.

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26