Autor Beitrag
lincore
Hält's aus hier
Beiträge: 15

Kubuntu 8.04, Debian lenny, Windows XP, Windows Vista
Delphi 2009, C++, Python, Lua
BeitragVerfasst: Sa 10.01.09 00:08 
Nabend,

als ich dachte TXMLDocument so halbwegs verstanden zu haben, bekam ich beim Laden einer XML-Datei immer wieder merkwürdige Fehler (Exceptions, Access Violations). Ich habe dann gelesen dass man tunlichst darauf achten sollte, create einen Besitzer statt nil als Parameter mitzugeben. Also habe ich das getan und nun läufts plötzlich wie am Schnürchen.
Trotzdem bin ich ein wenig unsicher geworden und möchte sicherstellen, dass ich keinen Mist gebaut habe. Wäre jemand der ein wenig erfahrener im Umgang mit TXMLDocument (und TTreeView) ist als ich (was nicht schwer sein dürfte) so freundlich meinen Code zu überfliegen und mir eventuelle Fehler mitzuteilen?
Schonmal vielen Dank für die Mühe.

Hier meine Unit:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
unit XML;

// XML.pas:
// -----------------------------------------------------------------------------
// This unit contains procedures to store data from a TTreeView instance in an
// xml-file (2do project file with .x2d extension) and vice versa.
// Since these routines are highly specified, in future releases this unit
// should be refactored into an all-purpose class that can store any kind of
// data without relying on TXMLDocument. Also, instead of using TTreeView's
// mediocre data pointer, a system independent n-ary tree structured data class
// should be implemented.
// -----------------------------------------------------------------------------
// Note:   The code in this unit is based on an xml tutorial by Zarko Gajic.
//         It can be found here:
//        http://delphi.about.com/library/weekly/aa101904a.htm

//!: Use a (generic) tree data class instead of TTreeView.Data.
//!: replace TXmlDocument with MS-less xml-parser.
//!: add try...except/finally blocks


interface //====================================================================
uses ComCtrls;

procedure xmlToTree(filename: string; tree: TTreeView);
procedure treeToXML(filename: string; tree: TTreeView);



implementation //===============================================================
uses Forms, SysUtils, XMLdoc, XMLIntf, Classes,
     Global, Job;


procedure xmlToTree(filename: string; tree: TTreeView);
var
  iNode : IXMLNode;
  xmldoc: TXMLDocument;
  //fileVersion: double;
  function getAttribute(const node: IXMLNode; const attr: string;
                        const default: string = ''): oleVariant;
  begin
    if node.HasAttribute(attr) then  result := string(node.Attributes[attr])
    else result := default;
  end// getAttribute
  procedure processNode(node: IXMLNode; treeNode: TTreeNode);
  var
    childNode : iXMLNode;
  begin
    if (node = nilor (node.NodeName <> 'item'then exit();
    if node.HasAttribute('name'then begin
      writeln(node.attributes['name']);
      treeNode := tree.Items.AddChild(treeNode, node.Attributes['name'])
    end else treeNode := tree.Items.AddChild(treeNode, '?! corrupt data');
    //!: (above) add improved error handling, logging and user feedback

    treeNode.ImageIndex     := integer(getAttribute(node, 'image''0'));
    treeNode.SelectedIndex  := treeNode.ImageIndex;

    treeNode.Data := TJob.create();
    TJob(treeNode.data).name         := treeNode.Text;
    TJob(treeNode.data).description := string(getAttribute(node, 'description'));
    TJob(treeNode.data).priority     := integer(getAttribute(node, 'priority''0'));
    TJob(treeNode.data).done        := boolean(getAttribute(node, 'done''false'));
    TJob(treeNode.data).autoDone    := boolean(getAttribute(node, 'autodone''false'));

    childNode := Node.ChildNodes.First;
    while childNode <> nil do
    begin
      ProcessNode(childNode, treeNode);
      childNode := childNode.NextSibling;
    end;
  end// processNode
begin
  if tree = nil then exit(); //!: user feedback?
  tree.items.Clear();
  xmlDoc := TXmlDocument.Create(application);
  xmlDoc.FileName := filename;
  xmlDoc.Active := true;
  iNode := xmlDoc.DocumentElement.ChildNodes.First;

  //!: check for valid x2d-document
  //!: check for newer/incompatible file version

  while iNode <> nil do
  begin
    processNode(iNode,nil);
    iNode := iNode.NextSibling;
  end;
  xmlDoc.Active := False;
  xmlDoc.destroy; //Gab ohne Owner eine Exception vom Typ EInvalidPointer
end;


procedure treeToXml(filename: string; tree: TTreeView);
var
  treeNode : TTreeNode;
  XMLDoc : TXMLDocument;
  iNode : IXMLNode;
  procedure processTreeItem(treeNode: TTreeNode; iNode: IXMLNode);
  var
    aNode: IXMLNode;
  begin
    if (treeNode = nilthen Exit;
    aNode := iNode.AddChild('item');
    aNode.Attributes['name'] := treeNode.Text;
    aNode.Attributes['image'] := treeNode.ImageIndex;
    aNode.Attributes['priority'] := TJob(treeNode.data).priority;
    aNode.Attributes['done'] := TJob(treeNode.data).done;
    aNode.Attributes['autodone'] := TJob(treeNode.data).autoDone;
    aNode.Attributes['description'] := TJob(treeNode.data).description;
    //child nodes
    treeNode := treeNode.getFirstChild;
    while treeNode <> nil do
    begin
      processTreeItem(treeNode, aNode);
      treeNode := treeNode.getNextSibling;
    end;
  end//processTreeItem
begin
  xmlDoc := TXMLDocument.Create(application);
  xmlDoc.Active := True;
  iNode := xmlDoc.AddChild('twodo');
  iNode.Attributes['x2d-version'] := Global.X2D_VERSION;

  treeNode := tree.TopItem;
  while treeNode <> nil do
  begin
    processTreeItem (treeNode, iNode);
    treeNode := treeNode.getNextSibling;
  end;

  xmlDoc.saveToFile(filename);
  xmlDoc.free();
end//treeToXML

end.


Zur Kontrolle hier nochmal eine vom Programm gespeicherte x2d-Datei:
ausblenden volle Höhe XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
<twodo x2d-version="1"><item name="Awesome 2.0" image="4" priority="0" done="false" autodone="false" description="{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Courier New;}}
{\colortbl ;\red0\green0\blue0;}
\viewkind4\uc1\pard\cf1\f0\fs20 Awesome 2.0 will be so awesome! you type in your birthday and it calculates how old you are! No more mysteries dude!!!!\par
\par
\b\fs40 Progress!!!!\b0\fs20\par
------------------------------------\par
\b\fs24 12/25/08: added skinable widgets!!!\par
12/26/08: added 3d wysiwyg editor!!\par
12/30/08: project abandoned.\b0\fs20\par
}
"
><item name="1: cool features!" image="1" priority="0" done="false" autodone="false" description="{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Courier New;}}
{\colortbl ;\red0\green0\blue0;}
\viewkind4\uc1\pard\cf1\f0\fs20 some of the cool features we are going to add!!!\par
}
"
><item name="1.1: skinable widgets" image="2" priority="0" done="true" autodone="false" description="{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Courier New;}{\f1\fnil\fcharset0 Modern;}{\f2\fnil\fcharset0 Small Fonts;}}
{\colortbl ;\red0\green128\blue0;\red0\green0\blue0;\red255\green0\blue0;\red0\green0\blue255;}
\viewkind4\uc1\pard\cf1\lang1033\b\i\f0\fs32 Skinable Widgets would be great! I copy and pasted some stuff and it looks awesome.\cf2\fs20  \b0\i0 ~slacker98\par
\cf3\ul\b\f1\fs28 COOL! Only problem's the access violations. What should we do about that?\cf2\ulnone\b0\f0\fs20  ~hentailover14\par
\cf1\b\i\fs80 Ignore!\cf2\b0\i0\fs20  ~slacker98\par
\cf4\f2\fs40 Good thinking!\cf2\f0\fs20  ~gangsta4life\par
}
"
/><item name="1.2: 3d wysiwyg editor" image="1" priority="0" done="false" autodone="false" description="{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Courier New;}{\f1\fnil\fcharset0 Arial;}}
{\colortbl ;\red0\green128\blue0;\red255\green0\blue0;\red0\green0\blue255;}
\viewkind4\uc1\pard\cf1\b\i\f0\fs32 doesnt run, cant find error!!!!!!!!!!! dont know why!!! gonna ask on the forums!!!! \fs20 ~slacker98\par
\cf2\i0\f1\fs40 Some dude from the forums said we should learn progaming!?! That bitch should play CS vs us!! Fucking nerd!!!! \fs20 ~ hentailover14\cf1\i\f0\fs32\par
\cf3 removed tutorial text, runs occasionaly now!!\cf1  \cf3\fs20 ~gangsta4life\par
}
"
/></item><item name="2: credits" image="0" priority="0" done="false" autodone="false" description="{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Courier New;}}
{\colortbl ;\red0\green128\blue0;\red0\green0\blue255;}
\viewkind4\uc1\pard\cf1\lang1033\ul\b\f0\fs32 We should credit ourselves. I mean, we are going to be the guys that will have been written this cool shit! \ulnone\b0 ~slacker98\par
\cf2\b\i Good idea!\b0\i0  ~gangsta4life\b\i\par
}
"
/></item></twodo>


Nochmals danke für die Mühe und allen ein schönes Wochenende,
lincore
lincore Threadstarter
Hält's aus hier
Beiträge: 15

Kubuntu 8.04, Debian lenny, Windows XP, Windows Vista
Delphi 2009, C++, Python, Lua
BeitragVerfasst: So 11.01.09 21:16 
(Ich schieb mal.)