问题
I want to browse through XML using a TTreeView. To associate the treeview nodes with the XML nodes with attributes I used the following syntax:
var tv: TTreeView; tn1, tn2: TTreeNode; xn: IXMLNode;
if xn.AttributeNodes.Count > 0 then
tn2 := tv.Items.AddChildObject( tn1, xn.NodeName, @xn )
else
tn2 := tv.Items.AddChild( tn1, xn.NodeName );
.. and later in the program:
var tv: TTreeView; pxn: ^IXMLNode; i: integer;
pxn := tv.Selected.Data;
for i := 0 to iXML.AttributeNodes.Count-1 do
ShowMessage ( pxn^.AttributeNodes[i].LocalName + ' = ' +
pxn^.AttributeNodes[i].Text );
which results in an exception.. As far as I can figure out this has to do with the fact that I'm point to an interface instead of an object.
Is it possible to reference the actual object of the XML instead of the interface? What will happen with this reference if new XML nodes are inserted in or deleted from the tree?
Or is there another straight forward solution?
All help appreciated!
回答1:
don't use @ and ^ operators, interfaces are already references
first code:
var tv: TTreeView; tn1, tn2: TTreeNode; xn: IXMLNode;
if xn.AttributeNodes.Count > 0 then
tn2 := tv.Items.AddChildObject( tn1, xn.NodeName, Pointer(xn) )
else
tn2 := tv.Items.AddChild( tn1, xn.NodeName );
second code (don't forget to check if data is assigned)
var tv: TTreeView; pxn: IXMLNode; i: integer;
if Assigned(tv.Selected) and Assigned(tv.Selected.Data) then begin
pxn := IXMLNode(tv.Selected.Data);
for i := 0 to iXML.AttributeNodes.Count-1 do
ShowMessage ( pxn.AttributeNodes[i].LocalName + ' = ' +
pxn.AttributeNodes[i].Text );
end;
Just search in the net for more information about interfaces, classes and the differences between them. Good information: http://blog.synopse.info/post/2012/02/29/Delphi-and-interfaces
来源:https://stackoverflow.com/questions/9788320/binding-an-xml-node-to-a-tree-view-node