在Delphi XE2中解析XML时发生访问冲突
我尝试使用以下代码在Delphi XE2中解析MusicBraniz XML文件:在Delphi XE2中解析XML时发生访问冲突,xml,delphi,delphi-xe2,musicbrainz,Xml,Delphi,Delphi Xe2,Musicbrainz,我尝试使用以下代码在Delphi XE2中解析MusicBraniz XML文件: webquery := 'http://www.musicbrainz.org/ws/2/recording/?query='+escape(tracktitle)+'&artist:'+escape(ArtistTitle); Log('WebQuery: ' + webquery, 0); begin XMLDoc:= TXMLDocument.Create(nil); XMLDoc.Fi
webquery := 'http://www.musicbrainz.org/ws/2/recording/?query='+escape(tracktitle)+'&artist:'+escape(ArtistTitle);
Log('WebQuery: ' + webquery, 0);
begin
XMLDoc:= TXMLDocument.Create(nil);
XMLDoc.FileName := webQuery;
XMLDoc.Active := True;
Log('Report: ' + XMLDoc.XML.Text, 0);
StartItemNode := XMLDoc.DocumentElement.ChildNodes.First.ChildNodes.FindNode('release-list') ;
ANode := StartItemNode;
repeat
Result.Album := ANode.ChildNodes['title'].Text; <-- Access Violation
Result.Status:= ANode.ChildNodes['status'].Text;
ANode := ANode.NextSibling;
until ANode = nil;
end;
webquery:='http://www.musicbrainz.org/ws/2/recording/?query=“+escape(tracktitle)+”和艺术家:“+escape(ArtistTitle);
日志('WebQuery:'+WebQuery,0);
开始
XMLDoc:=TXMLDocument.Create(无);
XMLDoc.FileName:=webQuery;
XMLDoc.Active:=True;
日志('Report:'+XMLDoc.XML.Text,0);
StartItemNode:=XMLDoc.DocumentElement.ChildNodes.First.ChildNodes.FindNode('release-list');
阳极:=星形电极;
重复
Result.Album:=阳极.ChildNodes['title'].Text 您存在访问冲突,因为FindNode
方法返回一个nil值,并且您试图访问一个无效的内存位置。为了使用FindNode
方法,您必须检查要搜索的节点的层次结构(级别),然后检查结果是否不是nil
试试这个样品
XMLDoc:= LoadXMLDocument(webQuery);
StartItemNode := XMLDoc.DocumentElement.ChildNodes.FindNode('recording-list');
if not Assigned(StartItemNode) then exit;
StartItemNode := StartItemNode.ChildNodes.FindNode('recording');
if Assigned(StartItemNode) then
begin
StartItemNode := StartItemNode.ChildNodes.FindNode('release-list');
if Assigned(StartItemNode) then
begin
StartItemNode := StartItemNode.ChildNodes.FindNode('release');
if Assigned(StartItemNode) then
begin
ANode := StartItemNode;
repeat
Result.Album := ANode.ChildNodes['title'].Text;
Result.Status:= ANode.ChildNodes['status'].Text;
ANode := ANode.NextSibling;
until ANode = nil;
end;
end;
end;
您存在访问冲突,因为FindNode
方法返回一个nil值,并且您试图访问一个无效的内存位置。为了使用FindNode
方法,您必须检查要搜索的节点的层次结构(级别),然后检查结果是否不是nil
试试这个样品
XMLDoc:= LoadXMLDocument(webQuery);
StartItemNode := XMLDoc.DocumentElement.ChildNodes.FindNode('recording-list');
if not Assigned(StartItemNode) then exit;
StartItemNode := StartItemNode.ChildNodes.FindNode('recording');
if Assigned(StartItemNode) then
begin
StartItemNode := StartItemNode.ChildNodes.FindNode('release-list');
if Assigned(StartItemNode) then
begin
StartItemNode := StartItemNode.ChildNodes.FindNode('release');
if Assigned(StartItemNode) then
begin
ANode := StartItemNode;
repeat
Result.Album := ANode.ChildNodes['title'].Text;
Result.Status:= ANode.ChildNodes['status'].Text;
ANode := ANode.NextSibling;
until ANode = nil;
end;
end;
end;
+1、你跑得更快。。。无论如何,我认为最好使用DOM和XPath。或者一个看起来很疯狂的XMLDoc.DocumentElement.ChildNodes.First.ChildNodes.First.ChildNodes.FindNode('release-list')
节点选择。和TIdURI.URLDecode
进行URL编码。当然,我始终建议使用XPath进行此类任务。谢谢,@RRUZ。到目前为止,我从未使用过XML,它确实让我感到困惑。你的解决方案帮我省了几个小时。我感谢你的帮助。+1,你更快了。。。无论如何,我认为最好使用DOM和XPath。或者一个看起来很疯狂的XMLDoc.DocumentElement.ChildNodes.First.ChildNodes.First.ChildNodes.FindNode('release-list')
节点选择。和TIdURI.URLDecode
进行URL编码。当然,我始终建议使用XPath进行此类任务。谢谢,@RRUZ。到目前为止,我从未使用过XML,它确实让我感到困惑。你的解决方案帮我省了几个小时。非常感谢您的帮助。您无法将URL传递到TXMLDocument.FileName
属性。如果需要解析远程XML文件,则必须首先通过其他方式在本地下载,如Indy的TIdHTTP
组件。在这种情况下,我建议使用TStream
而不是硬盘上的文件下载和解析XML。谢谢你的观察。About.com()上读取和操作XML文件的示例代码误导了我,我没有对此进行过多的思考。当然,这花了我很多钱。@Remy,你不需要。将URL传递到LoadXMLDocument
函数就足够了,正如我在(现已删除)注释中所建议的那样,就像RRUZ在他的回答中所建议的那样。LoadXMLDocument()
只创建一个TXMLDocument
并分配其FileName
属性。该属性不支持URL,只支持本地文件路径。@TLama:您依赖于基础引擎的特定于供应商的扩展名,在本例中是Windows上的MSXML。您不能将URL传递给TXMLDocument.FileName
属性。如果需要解析远程XML文件,则必须首先通过其他方式在本地下载,如Indy的TIdHTTP
组件。在这种情况下,我建议使用TStream
而不是硬盘上的文件下载和解析XML。谢谢你的观察。About.com()上读取和操作XML文件的示例代码误导了我,我没有对此进行过多的思考。当然,这花了我很多钱。@Remy,你不需要。将URL传递到LoadXMLDocument
函数就足够了,正如我在(现已删除)注释中所建议的那样,就像RRUZ在他的回答中所建议的那样。LoadXMLDocument()
只创建一个TXMLDocument
并分配其FileName
属性。该属性不支持URL,只支持本地文件路径。@TLama:您依赖于基础引擎的特定于供应商的扩展名,在本例中是Windows上的MSXML。