如何读取 XML 文件的所有子节点
Posted
技术标签:
【中文标题】如何读取 XML 文件的所有子节点【英文标题】:How to read all child nodes of an XML file 【发布时间】:2011-09-26 16:51:51 【问题描述】:我有这个文件:
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:app='http://purl.org/atom/app#' xmlns:media='http://search.yahoo.com/mrss/' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:gd='http://schemas.google.com/g/2005' xmlns:gml='http://www.opengis.net/gml' xmlns:yt='http://gdata.youtube.com/schemas/2007' xmlns:georss='http://www.georss.org/georss'>
<id>http://gdata.youtube.com/feeds/api/users/snifyy/favorites</id>
<updated>2011-09-26T16:21:40.933Z</updated>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://gdata.youtube.com/schemas/2007#video'/>
<title type='text'>Favorites of snifyy</title>
<logo>http://www.youtube.com/img/pic_youtubelogo_123x63.gif</logo>
<author>
<name>snifyy</name>
<uri>http://gdata.youtube.com/feeds/api/users/snifyy</uri>
</author>
<generator version='2.1' uri='http://gdata.youtube.com'>YouTube data API</generator>
<openSearch:totalResults>631</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
<entry>
<id>http://gdata.youtube.com/feeds/api/videos/LXO-jKksQkM</id>
<published>2011-09-23T16:15:27.000Z</published>
<updated>2011-09-26T16:21:15.000Z</updated>
<title type='text'>PUMPED UP KICKS|DUBSTEP</title>
<content type='text'>DUBSTEPPIN!!! to a beast track remixed by "butch clancy"</content>
<link rel='alternate' type='text/html' href='http://www.youtube.com/watch?v=LXO-jKksQkM&feature=youtube_gdata'/>
<link rel='http://gdata.youtube.com/schemas/2007#video.responses' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/LXO-jKksQkM/responses'/>
<link rel='http://gdata.youtube.com/schemas/2007#video.related' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/LXO-jKksQkM/related'/>
<link rel='http://gdata.youtube.com/schemas/2007#mobile' type='text/html' href='http://m.youtube.com/details?v=LXO-jKksQkM'/>
<link rel='related' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/LXO-jKksQkM'/>
<link rel='self' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/users/snifyy/favorites/LXO-jKksQkM'/>
<author>
<name>WHZGUD2</name>
<uri>http://gdata.youtube.com/feeds/api/users/whzgud2</uri>
</author>
<gd:comments>
<gd:feedLink href='http://gdata.youtube.com/feeds/api/videos/LXO-jKksQkM/comments' countHint='3738'/>
</gd:comments>
<media:group>
<media:category label='Entertainment' scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>Entertainment</media:category>
<media:content url='http://www.youtube.com/v/LXO-jKksQkM?f=user_favorites&app=youtube_gdata' type='application/x-shockwave-flash' medium='video' isDefault='true' expression='full' duration='327' yt:format='5'/>
<media:content url='rtsp://v3.cache5.c.youtube.com/CioLENy73wIaIQlDQiypjL5zLRMYDSANFEgGUg51c2VyX2Zhdm9yaXRlcww=/0/0/0/video.3gp' type='video/3gpp' medium='video' expression='full' duration='327' yt:format='1'/>
<media:content url='rtsp://v1.cache2.c.youtube.com/CioLENy73wIaIQlDQiypjL5zLRMYESARFEgGUg51c2VyX2Zhdm9yaXRlcww=/0/0/0/video.3gp' type='video/3gpp' medium='video' expression='full' duration='327' yt:format='6'/>
<media:description type='plain'>DUBSTEPPIN!!! to a beast track remixed by "butch clancy"</media:description>
<media:keywords>DUBSTEP, butch, clancy, bass</media:keywords>
<media:player url='http://www.youtube.com/watch?v=LXO-jKksQkM&feature=youtube_gdata_player'/>
<media:thumbnail url='http://i.ytimg.com/vi/LXO-jKksQkM/0.jpg' height='360' width='480' time='00:02:43.500'/>
<media:thumbnail url='http://i.ytimg.com/vi/LXO-jKksQkM/1.jpg' height='90' width='120' time='00:01:21.750'/>
<media:thumbnail url='http://i.ytimg.com/vi/LXO-jKksQkM/2.jpg' height='90' width='120' time='00:02:43.500'/>
<media:thumbnail url='http://i.ytimg.com/vi/LXO-jKksQkM/3.jpg' height='90' width='120' time='00:04:05.250'/>
<media:title type='plain'>PUMPED UP KICKS|DUBSTEP</media:title>
<yt:duration seconds='327'/>
</media:group>
<gd:rating average='4.96415' max='5' min='1' numRaters='24435' rel='http://schemas.google.com/g/2005#overall'/>
<yt:statistics favoriteCount='16660' viewCount='924793'/>
</entry>
</feed>
我想加载所有条目,然后加载它们的标题、内容和缩略图。但我什至在加载条目时遇到问题。这是我的代码(数据就是这个 xml):
XmlDocument xml = new XmlDocument();
xml.LoadXml(data);
XmlNodeList xnList = xml.SelectNodes("feed/entry");
foreach (XmlNode xn in xnList)
Debug.WriteLine(xn.LocalName.ToString());
【问题讨论】:
你从你展示的代码中得到了什么结果? xnList 是空的吗? 【参考方案1】:问题在于您的 XPath 没有指定名称空间(因此您实际上是在搜索具有空名称空间 URI 的名称)。鉴于feed
是***元素,这是一个非常简单的查询——我不认为使用XPath 实际上对您有帮助。试试这个,使用XmlElement.GetElementsByTagName
:
XmlElement root = doc.DocumentElement;
String atomUri = "http://www.w3.org/2005/Atom";
foreach (XmlElement element in root.GetElementsByTagName("entry", atomUri))
// Use element here
(如果您有机会使用 .NET 3.5,我建议您开始使用 LINQ to XML - 更好:)
编辑:这是一个简短但完整的程序,打印出每个 content
元素的 url
属性:
using System;
using System.Xml;
class Program
static void Main(string[] args)
XmlDocument doc = new XmlDocument();
doc.Load("test.xml");
XmlElement root = doc.DocumentElement;
String atomUri = "http://www.w3.org/2005/Atom";
String mediaUri = "http://search.yahoo.com/mrss/";
foreach (XmlElement entry in root.GetElementsByTagName("entry", atomUri))
foreach (XmlElement group in
entry.GetElementsByTagName("group", mediaUri))
foreach (XmlElement content in
entry.GetElementsByTagName("content", mediaUri))
Console.WriteLine(content.Attributes["url"].Value);
【讨论】:
请注意,OP 想要“入口”元素。 强烈同意为此使用 LINQ to XML。它比 XPath 容易得多。 OP指定了标签C#-2.0,所以可能是使用.net 2.0的技术限制 @blez:试试我现在给出的代码。它应该可以正常工作。我自己也试过了。 (我之前有一个错字。) @blez,当你说“我试过 X 和 Y”时,别忘了说结果如何。我们无法读心。【参考方案2】:您可以使用XmlNamespaceManager
从您的提要中指定命名空间:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(data);
XmlNamespaceManager manager = new XmlNamespaceManager(xDoc.NameTable);
manager.AddNamespace("atom", "http://www.w3.org/2005/Atom");
XmlNodeList xnList = xDoc.SelectNodes("atom:feed/atom:entry", manager);
foreach (XmlNode xn in xnList)
Debug.WriteLine(xn.LocalName.ToString());
任何类型的节点在选择节点时都使用命名空间前缀,例如:atom:feed/atom:entry
添加另一个命名空间以使用多个命名空间:
XmlNamespaceManager manager = new XmlNamespaceManager(xDoc.NameTable);
manager.AddNamespace("atom", "http://www.w3.org/2005/Atom");
manager.AddNamespace("media", "http://search.yahoo.com/mrss/");
XmlNodeList mediaNodes = xDoc.SelectNodes("atom:feed/atom:entry/media:group", manager);
【讨论】:
您需要将命名空间添加到管理器并使用适当的前缀。稍等,我补充一下。【参考方案3】:当您选择提要/条目元素时,您需要使用 Atom 命名空间。
创建一个命名空间管理器,为 Atom 命名空间添加一个命名空间前缀,然后在 XPath 表达式中使用它。
示例代码,请参阅this question 接受的答案。
【讨论】:
【参考方案4】:这里有一些帮助 - http://www.kirupa.com/forum/showthread.php?292473-Reading-Child-nodes-from-XML-file-C
还有How to read/write nodes and child nodes from xml file in c# maybe using xpath?
【讨论】:
以上是关于如何读取 XML 文件的所有子节点的主要内容,如果未能解决你的问题,请参考以下文章