【问题标题】:Access violation parsing XML-file to clientdataset将 XML 文件解析为客户端数据集的访问冲突
【发布时间】:2019-11-12 15:51:21
【问题描述】:

下面是一个将 xml 文件读入客户端数据集的过程。 我的代码在我不理解的“d-loop”的第二次迭代中导致访问冲突错误。 daynode.childnodes 导致消息:访问冲突在 00000000 访问 00000000

在第一次迭代中,dayNode.childnodes 是一个指向带有节点的列表(IXMLnodelist)的指针。在第 2 次迭代中,dayNode 跳转到第 2 天标签。 2nd文件里也有一些children,但是为什么会导致报错呢?

更新:我添加了 addTocds 和 encodeStrToTdate 程序。 cds 具有以下字段('Projectnr':字符串,'weeknr':整数,'jaar':整数,'ma'...'zo':float)
看起来 addTocds 过程 (locate) 有问题,因为如果我将 '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.

【问题讨论】:

  • 可能您正在使用 MSXML.Pas,提供的导入单元。它是从哪个版本的 MSXml.Dll 生成的?西雅图的那个,f.i.来自 C:\WINDOWS\system32\msxml6.dll。根据进口商自动生成的cmets。顺便说一句,请将encodeStrToTDate的来源添加到您的q中。
  • 注释掉encodeStrToDateaddTocds,您的代码在Delphi Seattle 中编译并运行良好。所以你需要编辑你的 q 以便它包含的代码构成一个MRE。否则它可能会被关闭,然后没有人可以发布答案。将来,请首先发布 MRE。
  • @MartynA 所以我们现在称他们为 MRE?我记得是SSCCE的时候。 MRE 让我想起军粮。
  • @JerryDodge:是的,显然。我自己更喜欢 MCVE ...
  • 我总是只使用[mcve] magic-link,它会重定向到最新的文章(目前是[mre] article)。

标签: xml delphi delphi-2010


【解决方案1】:

我找到了解决方案,但还不知道为什么这是解决方案。因为我对接口缺乏了解。 xmldoc 对象的类型应该是 Ixmldocument 而不是 TXMLdocument。进行此更改后,一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多