下面是将xml文件读入到客户端数据集中的过程。我的代码在'd-loop‘的第二次迭代中导致了一个访问冲突错误,这是我不理解的。daynode.childnodes导致消息:在00000000访问00000000时发生访问冲突
在第一次迭代中,dayNode.childnodes是一个指向包含节点的列表(IXMLnodelist)的指针。在第二次迭代中,dayNode跳转到第二天标记。第二个文件中也有一些子项,但为什么这会导致错误?
更新:我添加了addTocds和encodeStrToTdate过程。cds有以下字段('Projectnr':字符串,'weeknr':整数,'jaar':整数,'ma'...'zo':浮点)
它看起来在定位过程中有问题,因为如果我将'if locate..then‘替换为'if false then',每一条记录都会被添加到cds中。
<?xml version="1.0" standalone="yes"?>
<ROOT>
<DAY>
<DATE>12-10-2019</DATE>
<STATUS > 1 </STATUS>
<PROJECTS>
<PROJECT nr = "190000"> 5</PROJECT>
<PROJECT nr = "190001"> 3</PROJECT>
</PROJECTS>
</DAY>
<DAY>
<DATE>11-10-2019</DATE>
<STATUS > 1 </STATUS>
<PROJECTS>
<PROJECT nr = "190000"> 3.4 </PROJECT>
<PROJECT nr = "190001"> 4 </PROJECT>
</PROJECTS>
</DAY>
<DAY>
<DATE>13-10-2019</DATE>
<STATUS > 2 </STATUS>
<PROJECTS>
<PROJECT nr = "190000"> 6 </PROJECT>
<PROJECT nr = "190001"> 7 </PROJECT>
</PROJECTS>
</DAY>
</ROOT>const
daysOfWeek: array [ 1 .. 7 ] of string = ( 'ma', 'di', 'wo', 'do', 'vr', 'za', 'zo' );
procedure addTocds( cds: Tclientdataset; dag: integer; week: integer; jaar: integer; pn: string; uren: double );
// dag: day of the week
// week: week of the year
try
with cds do
begin
if not active then Open;
first;
if locate('PROJECTNR;WEEKNR;JAAR', varArrayOf( [pn, week, jaar] ), [loCaseInsensitive] ) then
begin
Edit;
FieldByName( daysOfWeek[ dag ] ).asfloat := uren; //floattostr( uren );
post;
end
else
begin
cds.first;
append;
FieldByName( daysOfWeek[ dag ] ).asfloat := uren;
fieldbyname('PROJECTNR').asstring := pn;
FieldByName('WEEKNR').asinteger := week;
FieldByName('JAAR').asinteger := jaar;
Post;
end;
end;
except
on E:exception do
begin
outputdebugstring(Pchar(e.message));
end;
end;
end;
// the strTodate routine result in 3-12-1899 in all cases so I made this (temporarily) function
function encodeStrToTdate(xmlstring: string ): TDate;
var
position :integer;
daystr, monthstr, yearstr: string;
begin
position :=pos('-', xmlstring);
daystr := copy(xmlstring, 1, position-1);
delete(Xmlstring,1,position);
position :=pos('-', xmlstring);
monthstr := copy(xmlstring, 1, position-1);
delete(Xmlstring,1,position);
yearstr := xmlstring;
result := encodedate(strtoint(yearstr), strtoint(monthstr), strtoint(daystr));
end;
// lees XML en laadt de XML in een TXMLdocument en open het document
procedure TAVIVparseXML.parseXML( XMLdoc: TXMLdocument; cds: Tclientdataset );
var // XMLdoc : TXMLdocument;
statusnode, mainnode, dayNode, datenode, projectNode, projectsNode: IXMLnode;
dayNodes: IXMLnodelist;
uren: string;
d,p : integer;
datestr: string;
pn: string;
dateobj : Tdate;
begin
try
mainnode := XMLdoc.DocumentElement; // ROOT
dayNodes := mainnode.childnodes;
for d := 0 to mainnode.ChildNodes.Count - 1 do // DAY
begin
dayNode := daynodes.nodes[d]; //mainnode.ChildNodes[de]; //.nodes[de];//.get(d); //[ d ]; // DAY
if (daynode.NodeName = 'DAY') then
begin
dateNode := dayNode.childnodes.FindNode('DATE');
projectsNode := dayNode.childnodes.findNode('PROJECTS');
statusNode := dayNode.ChildNodes.FindNode('STATUS');
if(((dateNode <> nil) and (projectsNode <> nil)) and ((statusNode <> nil))) then
begin
datestr := dateNode.text;
dateobj := encodeStrToTDate(datestr);
if projectsNode <> nil then
begin
for p := 0 to projectsNode.childnodes.Count - 1 do //PROJECTS-> PROJECT
begin
projectNode := projectsNode.childnodes.nodes[p]; //.get(p);
pn := projectNode.attributes['nr'];
uren := Trim(projectNode.text);
addTocds( cds, dayOfTheweek(dateobj), weekoftheyear(dateobj), yearOf(dateobj), pn,strTofloat(uren));
end;
end;
end;
end;
end;
except// finally
outputdebugstring(Pchar('error parseXML')); // freeandnil(XMLdoc);
end;
end;
end.发布于 2019-11-19 03:00:58
我找到了解决方案,但还不知道为什么这就是解决方案。因为我缺乏关于接口的知识。xmldoc对象的类型应该是Ixmldocument,而不是TXMLdocument。在此更改之后,一切都运行得很好。
https://stackoverflow.com/questions/58822174
复制相似问题