我尝试使用以下代码解析Delphi XE2中的MusicBraninz 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.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;
正确获取XML文件,看起来像下面的内容:
<metadata xmlns="http://musicbrainz.org/ns/mmd-2.0#" xmlns:ext="http://musicbrainz.org/ns/ext#-2.0">
<recording-list offset="0" count="1">
<recording ext:score="100" id="a399eec1-d45d-4505-b475-ead0da6cad17">
<title>Mestecăniș</title>
<length>359000</length>
<artist-credit>
<name-credit>
<artist id="8fb78a16-0cba-4175-8c92-d9645dfb007d">
<name>Bucovina</name>
<sort-name>Bucovina</sort-name>
</artist>
</name-credit>
</artist-credit>
<release-list>
<release id="22b00afc-86ea-445a-8805-b6bfa33da74e">
<title>Duh</title>
<status>Official</status>
<release-group type="EP" id="4e8fb87c-3760-48c1-a3d7-88e7a2c839fa">
<primary-type>EP</primary-type>
</release-group>
<date>2010</date>
<country>RO</country>
<medium-list>
<track-count>5</track-count>
<medium>
<position>1</position>
<format>CD</format>
<track-list offset="3" count="5">
<track>
<number>4</number>
<title>Mestecăniș</title>
<length>359000</length>
</track>
</track-list>
</medium>
</medium-list>
</release>
</release-list>
</recording>
</recording-list>
</metadata>
我的问题是:我在这里做错了吗?声明并初始化所有变量。
谢谢,
答案 0 :(得分:5)
您有访问冲突,因为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;