为什么同样一个xml文件,第二次打开就出错呢 ( 积分: 50 )

  • 主题发起人 主题发起人 vigor0709
  • 开始时间 开始时间
V

vigor0709

Unregistered / Unconfirmed
GUEST, unregistred user!
我做一个循环,第一次打开这个xml还是可以的
但是第二次读入相同的xml,就报错
说什么read of address 00000000
这是为什么呢
我以为是初始化的问题
所以第一次读完我就吧active设置为假
可还是不行
 
我做一个循环,第一次打开这个xml还是可以的
但是第二次读入相同的xml,就报错
说什么read of address 00000000
这是为什么呢
我以为是初始化的问题
所以第一次读完我就吧active设置为假
可还是不行
 
你肯定是动态创建 xmldoc 的,而且创建时的 owner 是 nil ?
建议使用 IXMLDocument:
function TMainForm.CreateXMLDoc(AWithHeader: Boolean): IXMLDocument;
procedure SwitchDomVendor(AXMLDoc: TXMLDocument);
begin
if RadioButton1.Checked then
AXMLDoc.DOMVendor := MSXML_DOM
else
if RadioButton2.Checked then
AXMLDoc.DOMVendor := OpenXMLFactory
else
AXMLDoc.DOMVendor := XercesDOM;
end;
const
defXMLDocVersion = '1.0';
defXMLDocEncoding = 'UTF-8';
var
XMLDoc: TXMLDocument;
begin
XMLDoc := TXMLDocument.Create(nil);
SwitchDomVendor(XMLDoc);
Result := XMLDoc;
if AWithHeader then
with Resultdo
begin
Active := True;
Version := defXMLDocVersion;
Encoding := defXMLDocEncoding;
end;
end;

使用:
procedure TMainForm.LoadFromXML1;
var
RootNode: IXMLNode;
Node: IXMLNode;
I: Integer;
XMLDoc: IXMLDocument;
begin
{$IFDEF XML_VCL}
XMLDoc := CreateXMLDoc(True);
XMLDoc.LoadFromFile(defAttribsFile);
RootNode := XMLDoc.DocumentElement;
Assert(RootNode <> nil);
for I := 0 to RootNode.ChildNodes.Count - 1do
begin
Node := RootNode.ChildNodes.Get(I);
Assert(Node <> nil);
TTestObject(FList.Items).Property1 := Node.Attributes['Property1'];
TTestObject(FList.Items).Property2 := Node.Attributes['Property2'];
TTestObject(FList.Items).Property3 := Node.Attributes['Property3'];
TTestObject(FList.Items).Property4 := Node.Attributes['Property4'];
TTestObject(FList.Items).Property5 := Node.Attributes['Property5'];
TTestObject(FList.Items).Property6 := Node.Attributes['Property6'];
TTestObject(FList.Items).Property7 := Node.Attributes['Property7'];
TTestObject(FList.Items).Property8 := Node.Attributes['Property8'];
TTestObject(FList.Items).Property9 := Node.Attributes['Property9'];
end;
end;
 
我不太明白楼上的意思,因为使用xml很少
请您仔细说明一下
下面是我循环体的函数,您看具体怎么改
在这之前我已经拖了一个Txmldocument控件了
procedure TForm1.getData(XMLfile: string);
var
channel,item,first:IXMLNode;
title,link,description,pubDate,category:string;
newItem:TListItem;
i,flag:integer;
begin
flag:=0;
xmldocument1.FileName:=XMLfile;
// set active
xmldocument1.Active:=true;
newItem:=nil;
// locate
channel:=xmldocument1.DocumentElement.ChildNodes[0];
item:=channel.ChildNodes['item'];
//count the count of items.
first:=item;
while item.NextSibling <> nildo
begin
inc(count);
item:=item.NextSibling;
end;
//getitem and display
item:=first;
for i:=0 to countdo
begin
// snap the data
title:=item.ChildNodes['title'].text;
link:=item.ChildNodes['link'].Text;
description:=item.ChildNodes['description'].Text;
pubDate:=item.ChildNodes['pubDate'].Text;
category:=item.ChildNodes['category'].Text;
// save the data to database
// to protect to write the data that already exists
adotable1.First;
while not adotable1.Eof do
begin
if adotable1.FieldByName('title').asstring = title then
begin
flag:=1;
break;
end;
adotable1.Next;
end;
// write date to database
if flag = 0 then
begin
adotable1.Append;
adotable1.FieldByName('title').Value:=title;
adotable1.FieldByName('link').Value:=link;
adotable1.FieldByName('description').Value:=description;
adotable1.FieldByName('pubDate').Value:=pubDate;
adotable1.FieldByName('category').value:=category;
adotable1.Post;
end;
// display the xml data to Listview
newItem:=listview1.Items.Add;
newItem.Caption:=title;
newItem.ImageIndex:=1;
item:=item.NextSibling;
end;

end;
请斧正
 
请问Lsuper先生还在线上吗
好着急
期待ing
 
刚才我根据你的方法去做了
可是还是跟上次一样错误
您来看看好吗
 
for i:=0 to countdo
看一下这个边界条件,是否应该是Count-1,另外,跟踪一下,看执行到哪里会出现read of address 00000000错误
 
就是执行到第二次打开一个xml文件把active属性设置为真的时候就这样。
我把整个pas文件给你看看吧
unit RssReader;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtrls, SHDocVw, ExtCtrls, xmldom, XMLIntf,
msxmldom, XMLDoc, DB, ADODB, ComCtrls, ImgList;
type
TForm1 = class(TForm)
Panel1: TPanel;
WebBrowser1: TWebBrowser;
XMLDocument1: TXMLDocument;
ADOTable1: TADOTable;
DataSource1: TDataSource;
ListView1: TListView;
ImageList1: TImageList;
TreeView1: TTreeView;
XMLDocument2: TXMLDocument;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure ListView1Click(Sender: TObject);
procedure ListView1DblClick(Sender: TObject);
procedure ListView1DrawItem(Sender: TCustomListView;
Item: TListItem;
Rect: TRect;
State: TOwnerDrawState);
proceduredo
mToTree (XmlNode: IXMLNode;
TreeNode: TTreeNode);
procedure getData(XMLfile:string);
procedure TreeView1DblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
// public paraments
count:integer;
flag : Integer;
Ptitle,Plink:string;
cv_name,cv_link:array[0..10] of string;
implementation
{$R *.dfm}
procedure TForm1.DomToTree(XmlNode: IXMLNode;
TreeNode: TTreeNode);
var
I: Integer;
NewTreeNode: TTreeNode;
NodeText: string;
AttrNode: IXMLNode;
begin
// skip text nodes and other special cases
if not (XmlNode.NodeType = ntElement) then
Exit;
// add the node itself
NodeText := XmlNode.NodeName;
if XmlNode.IsTextElement then
NodeText := NodeText + ' = ' + XmlNode.NodeValue;
if xmlnode.HasAttribute('name')=true then
nodetext := xmlnode.Attributes['name'];
// if nodename equals 'link',end it. then
write to array
if xmlnode.NodeName <> 'link' then
NewTreeNode := TreeView1.Items.AddChild(TreeNode, NodeText)
else
begin
cv_name[strtoint(xmlnode.NextSibling.Text)]:=xmlnode.ParentNode.Attributes['name'];
cv_link[strtoint(xmlnode.NextSibling.Text)]:=xmlnode.Text;
end;
// add each child node
if XmlNode.HasChildNodes then
for I := 0 to xmlNode.ChildNodes.Count - 1do
begin
if xmlnode.ChildNodes.NodeName <> 'order' then
do
mToTree (xmlNode.ChildNodes.Nodes , NewTreeNode);
end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
count:=0;
flag:=0;
memo1.Clear;
DomToTree (XMLDocument2.DocumentElement, nil);
end;

procedure TForm1.getData(XMLfile: string);
var
channel,item,first:IXMLNode;
title,link,description,pubDate,category:string;
newItem:TListItem;
i,flag:integer;
begin
flag:=0;
xmldocument1.FileName:=XMLfile;
// set active
xmldocument1.Active:=true;
newItem:=nil;
// locate
channel:=xmldocument1.DocumentElement.ChildNodes[0];
item:=channel.ChildNodes['item'];
//count the count of items.
first:=item;
while item.NextSibling <> nildo
begin
inc(count);
item:=item.NextSibling;
end;
//getitem and display
item:=first;
for i:=0 to countdo
begin
// snap the data
title:=item.ChildNodes['title'].text;
link:=item.ChildNodes['link'].Text;
description:=item.ChildNodes['description'].Text;
pubDate:=item.ChildNodes['pubDate'].Text;
category:=item.ChildNodes['category'].Text;
// save the data to database
// to protect to write the data that already exists
adotable1.First;
while not adotable1.Eof do
begin
if adotable1.FieldByName('title').asstring = title then
begin
flag:=1;
break;
end;
adotable1.Next;
end;
// write date to database
if flag = 0 then
begin
adotable1.Append;
adotable1.FieldByName('title').Value:=title;
adotable1.FieldByName('link').Value:=link;
adotable1.FieldByName('description').Value:=description;
adotable1.FieldByName('pubDate').Value:=pubDate;
adotable1.FieldByName('category').value:=category;
adotable1.Post;
end;
// display the xml data to Listview
newItem:=listview1.Items.Add;
newItem.Caption:=title;
newItem.ImageIndex:=1;
item:=item.NextSibling;
end;

end;
procedure TForm1.ListView1Click(Sender: TObject);
var
locate:integer;
begin
if listview1.Selected <> nil then
begin
memo1.Clear;
locate:=listview1.Selected.Index;
adotable1.Locate('title',listview1.Items[locate].Caption,[loCaseInsensitive]);
memo1.Lines.Add(adotable1.Fields[0].AsString);
memo1.Lines.Add(adotable1.Fields[2].AsString);
Plink:=adotable1.Fields[1].AsString;
memo1.Lines.Add(Plink);
end;
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
var
text:string;
index:integer;
insertItem:TlistItem;
begin
webbrowser1.Navigate(Plink);
listview1.Selected.cut:=true;
text:=listview1.Selected.Caption;
index:=listview1.Selected.Index;
listview1.Selected.Delete;
insertitem:=listview1.items.insert (index);
insertitem.Caption:=text;
end;

procedure TForm1.ListView1DrawItem(Sender: TCustomListView;
Item: TListItem;
Rect: TRect;
State: TOwnerDrawState);
begin
listview1.Canvas.Font.Color:=clblue;
end;

procedure TForm1.TreeView1DblClick(Sender: TObject);
var
i:integer;
begin
for i:=0 to 9do
begin
if cv_name = treeview1.Selected.Text then
begin
//showmessage(cv_link);
getdata(cv_link);
end;
end;
end;

end.

麻烦你了
 
好的,我试试
 
把你的文件发到dawnsong@sohu.com里,
这么调着有点儿麻烦
 
需要xml文件吗?在新华网的rss网页中
http://www.xinhuanet.com/rss.htm
 
给你发回去了,你原先的问题不存在了,非法内存访问就是些边界条件的事;看你的那些xml 文件很杂乱,我也不想继续修改了。不过好像也只有“新浪房产”才能够不断的双击操作,现在双击多少次也不会再出问题了[8D]
其他的问题估计需要你自己进一步开发的事了,其他的不能打开应该是你还没做完吧[:)]
 
我还是没有收到啊
 
又发了一次
 
unit RssReader;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtrls, SHDocVw, ExtCtrls, xmldom, XMLIntf,
msxmldom, XMLDoc, DB, ADODB, ComCtrls, ImgList, ActiveX;
type
TForm1 = class(TForm)
Panel1: TPanel;
WebBrowser1: TWebBrowser;
XMLDocument1: TXMLDocument;
ADOTable1: TADOTable;
DataSource1: TDataSource;
ListView1: TListView;
ImageList1: TImageList;
TreeView1: TTreeView;
XMLDocument2: TXMLDocument;
Memo1: TMemo;
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure ListView1Click(Sender: TObject);
procedure ListView1DblClick(Sender: TObject);
procedure ListView1DrawItem(Sender: TCustomListView;
Item: TListItem;
Rect: TRect;
State: TOwnerDrawState);
proceduredo
mToTree (XmlNode: IXMLNode;
TreeNode: TTreeNode);
procedure getData(XMLfile:string);
procedure TreeView1DblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
// public paraments
count:integer;
flag : Integer;
Ptitle,Plink:string;
cv_name,cv_link:array[0..10] of string;
implementation
{$R *.dfm}
procedure TForm1.DomToTree(XmlNode: IXMLNode;
TreeNode: TTreeNode);
var
I: Integer;
NewTreeNode: TTreeNode;
NodeText: string;
AttrNode: IXMLNode;
begin

if not (XmlNode.NodeType = ntElement) then
Exit;
NodeText := XmlNode.NodeName;
if XmlNode.IsTextElement then
NodeText := NodeText + ' = ' + XmlNode.NodeValue;
if xmlnode.HasAttribute('name')=true then
nodetext := xmlnode.Attributes['name'];
// if nodename equals 'link',end it. then
write to array
if xmlnode.NodeName <> 'link' then
NewTreeNode := TreeView1.Items.AddChild(TreeNode, NodeText)
else
begin
cv_name[strtoint(xmlnode.NextSibling.Text)]:=xmlnode.ParentNode.Attributes['name'];
cv_link[strtoint(xmlnode.NextSibling.Text)]:=xmlnode.Text;
end;
// add each child node
if XmlNode.HasChildNodes then
for i:= 0 to xmlNode.ChildNodes.Count - 1do
if xmlnode.ChildNodes.NodeName <> 'order' then
do
mToTree (xmlNode.ChildNodes.Nodes, NewTreeNode);
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
count:=0;
flag:=0;
ADOTable1.Active :=True;
memo1.Clear;
do
mToTree (XMLDocument2.DocumentElement, nil);
end;

procedure TForm1.getData(XMLfile: string);
var
channel,item,first:IXMLNode;
title,link,description,pubDate,category:string;
newItem:TListItem;
i,flag:integer;
begin
flag:=0;
xmldocument1.Active :=False;
xmldocument1.FileName:='';
xmldocument1.FileName:=ExtractFilePath(Application.ExeName) + XMLfile;
xmldocument1.Active :=True;
try
newItem:=nil;
channel:=xmldocument1.DocumentElement.ChildNodes[0];
item:=channel.ChildNodes['item'];
first:=item;
while item.NextSibling <> nildo
begin
inc(count);
item:=item.NextSibling;
end;
item:=first;
for i:=0 to count-1do
begin
title:=item.ChildNodes['title'].text;
link:=item.ChildNodes['link'].Text;
description:=item.ChildNodes['description'].Text;
pubDate:=item.ChildNodes['pubDate'].Text;
category:=item.ChildNodes['category'].Text;
adotable1.First;
flag :=0;
while not adotable1.Eof do
begin
if adotable1.FieldByName('title').asstring = title then
begin
flag:=1;
break;
end;
adotable1.Next;
end;
// write date to database
if flag = 0 then
begin
adotable1.Append;
adotable1.FieldByName('title').Value:=title;
adotable1.FieldByName('link').Value:=link;
adotable1.FieldByName('description').Value:=description;
adotable1.FieldByName('pubDate').Value:=pubDate;
adotable1.FieldByName('category').value:=category;
adotable1.Post;
end;
// display the xml data to Listview
newItem:=listview1.Items.Add;
newItem.Caption:=title;
newItem.ImageIndex:=1;
if item.NextSibling<>nil then
item:=item.NextSibling
else
Break;
end;
finally
xmldocument1.Active :=False;
xmldocument1.FileName:='';
end;
end;
procedure TForm1.ListView1Click(Sender: TObject);
var locate:integer;
begin
if listview1.Selected <> nil then
begin
memo1.Clear;
locate:=listview1.Selected.Index;
adotable1.Locate('title',listview1.Items[locate].Caption,[loCaseInsensitive]);
memo1.Lines.Add(adotable1.Fields[0].AsString);
memo1.Lines.Add(adotable1.Fields[2].AsString);
Plink:=adotable1.Fields[1].AsString;
memo1.Lines.Add(Plink);
end;
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
var
text:string;
index:integer;
insertItem:TlistItem;
begin
webbrowser1.Navigate(Plink);
if ListView1.Selected<>nil then
//此处已更改
begin
listview1.Selected.cut:=true;
text:=listview1.Selected.Caption;
index:=listview1.Selected.Index;
listview1.Selected.Delete;
insertitem:=listview1.items.insert (index);
insertitem.Caption:=text;
end;
end;

procedure TForm1.ListView1DrawItem(Sender: TCustomListView;
Item: TListItem;
Rect: TRect;
State: TOwnerDrawState);
begin
listview1.Canvas.Font.Color:=clblue;
end;

procedure TForm1.TreeView1DblClick(Sender: TObject);
var
i:integer;
begin
for i:=0 to 9do
begin
if cv_name = treeview1.Selected.Text then
begin
//showmessage(cv_link);
getdata(cv_link);
end;
end;
end;

procedure TForm1.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
ADOTable1.Close;
end;

initialization
CoInitialize(nil);
finalization
CoUninitialize;
end.
这么贴上来了
 
接受答案了.
 
后退
顶部