XPath与XmlDocument没有找到节点
问题描述:
所以我遇到了一些麻烦,我的XPath没有从XML树中选择任何节点。这是我的代码到目前为止:XPath与XmlDocument没有找到节点
var reader = new XmlDocument();
reader.Load(@"http://www.fieldgulls.com/rss/current");
XmlNodeList list = reader.SelectNodes("./entry");
我也尝试XPath值的* /条目,/ /条目,和其他人。我似乎无法得到任何工作,但。我究竟做错了什么?
答
问题是<Entry>
实际上是在根节点的默认名称空间中的元素,这是"http://www.fieldgulls.com/rss/current"
:
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"> <!--The default namespace for nested elements is set here with the xmlns= attribute -->
<title>Field Gulls - All Posts</title>
<subtitle>The stupidest name in smart football analysis.</subtitle>
<icon>https://cdn3.vox-cdn.com/community_logos/50215/fieldgulls-fav.png</icon>
<updated>2016-11-13T17:00:02-08:00</updated>
<id>http://www.fieldgulls.com/rss/current/</id>
<link type="text/html" href="http://www.fieldgulls.com/" rel="alternate"/>
<entry>
<!--Remainder commented out-->
因此需要使用适当的名称空间和适当SelectNodes()
倍率选择节点:
var reader = new XmlDocument();
reader.Load(@"http://www.fieldgulls.com/rss/current");
var nsmgr = new XmlNamespaceManager(reader.NameTable);
nsmgr.AddNamespace("a", "http://www.w3.org/2005/Atom");
XmlNodeList list = reader.SelectNodes(".//a:entry", nsmgr);
在这样的情况下,我发现它有助于使用以下调试工具的基础上,新LINQ to XML类库,使每个节点的命名空间appare NT:
public static class XObjectExtensions
{
public static IEnumerable<string> DumpXmlElementNames(this XDocument doc)
{
return doc.Root.DumpXmlElementNames();
}
public static IEnumerable<string> DumpXmlElementNames(this XElement root)
{
if (root == null)
return Enumerable.Empty<string>();
var startCount = root.AncestorsAndSelf().Count();
return root.DescendantsAndSelf().Select(el => string.Format("{0}\"{1}\"",
new string(' ', 2 * (el.AncestorsAndSelf().Count() - startCount)), el.Name.ToString()));
}
}
然后,在调试的时候,你会怎么做:
Console.WriteLine("Dumping a list of all element names and namespaces: ");
Console.WriteLine(String.Join("\n", XDocument.Load(@"http://www.fieldgulls.com/rss/current").DumpXmlElementNames()));
其产生开头输出:
"{http://www.w3.org/2005/Atom}feed"
"{http://www.w3.org/2005/Atom}title"
"{http://www.w3.org/2005/Atom}subtitle"
"{http://www.w3.org/2005/Atom}icon"
"{http://www.w3.org/2005/Atom}updated"
"{http://www.w3.org/2005/Atom}id"
"{http://www.w3.org/2005/Atom}link"
"{http://www.w3.org/2005/Atom}entry"
样品fiddle。
答
尝试使用SyndicationFeed类。使用RSS很容易。
using (var xmlReader = XmlReader.Create(@"http://www.fieldgulls.com/rss/current"))
{
var feed = SyndicationFeed.Load(xmlReader);
foreach (var item in feed.Items)
{
// use item.Title.Text and so on
}
}
您的XML节点可能位于名称空间中,但没有[mcve]我们无法确定。你可以编辑你的问题来包含XML吗?或者参见[在C#中使用带默认命名空间的Xpath](https://*.com/questions/585812/using-xpath-with-default-namespace-in-c-sharp/2911160#2911160)选择具有名称空间的节点。 – dbc
哦 - '“http://www.fieldgulls.com/rss/current”'是实际的实时URL。在这种情况下,''节点的正确命名空间是'xmlns =“http://www.w3.org/2005/Atom”' –
dbc