This is a full simplification of my code, but even so it doesn't work when class var ID_COUNTER is there, in this code I don't use the class var, but in my real code yes, but just the existence of this class variable makes the result of 's' different. This is the most weird I have ever seen.
Here is a simplification, but still doesn't Works, one Unit in 75 lines.
unit Umain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,XMLIntf,XmlDoc,IOUtils,XMLDom,System.Generics.Collections;
type
TStore = class
public
class var ID_COUNTER: Integer;
MainNode: IDomNode;
constructor create(node:IDomNode);
function getNode():IDomNode;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
FMain: TStore;
function Recursive(node:IDomNode):TStore;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Doc:IXMLDocument;
content: WideString;
html: IDomNode;
s: String;
begin
Doc := TXMLDocument.Create(Application);
Doc.LoadFromFile('C:\temp\example.xml');
Doc.Active := true;
html := Doc.DOMDocument.getElementsByTagName('html').item[0];
FMain := Recursive(html);
s := FMain.getNode().nodeName;
end;
function TForm1.Recursive(node: IDOMNode):TStore;
var
i: Integer;
store: TStore;
nodeName,nodeValue:String;
begin
store := TStore.create(node);
if(not node.hasChildNodes)then
Exit(store);
for i := 0 to node.childNodes.length-1 do
begin
Recursive(node.childNodes.item[i]);
end;
Exit(store);
end;
constructor TStore.create(node: IDOMNode);
begin
self.MainNode := node;
end;
function TStore.getNode:IDomNode;
begin
Result := self.MainNode;
end;
end.
Some notes:
example.xml is only a simple HTML document. Everything is broken when ID_COUNTER exists, if it is commented, everything is Ok. It happens here and in my real and wide Project.
The problem is that, syntactically, class var
introduces a class field block rather than a single class field, meaning that if you use class var
, all following field declarations in the same visibility section will be class variables too. So now, MainNode
becomes a class variable too and that probably causes the problems you encounter. Reformatting your code shows this a little more clearly:
public
class var
ID_COUNT: Integer;
MainNode: IDomNode;
constructor Create(... etc.
Your options are:
move ID_COUNT
one line down:
public
MainNode: IDomNode;
class var ID_COUNTER: Integer;
constructor Create(... etc.
create a special section for MainNode
:
public
class var ID_COUNTER: Integer;
public
MainNode: IDomNode;
constructor Create(... etc.
preface MainNode
with the var
keyword (which, likewise, introduces a block, specifically an instance field block within the current visibility section):
public
class var
ID_COUNTER: Integer;
// any other class variables
var
MainNode: IDomNode;
// any other instance variables
constructor Create(... etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With