问题是sitemapindex
元素定义了一个默认名称空间。您需要在选择节点时指定命名空间,否则将无法找到它们。例如:
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", "http://www.sitemaps.org/schemas/sitemap/0.9");
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
通常来说,使用XmlNameSpaceManager
时,你可以离开前缀为空字符串指定您希望该命名空间是默认的命名空间。所以,你会觉得你可以做这样的事情:
// WON'T WORK
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("", "http://www.sitemaps.org/schemas/sitemap/0.9"); //Empty prefix
XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap", manager); //No prefixes in XPath
但是,如果你尝试的代码,你会发现,它不会找到任何匹配的节点。原因是在XPath 1.0(这是XmlDocument实现的)中,当没有提供名称空间时,它始终使用空名称空间,而不是默认名称空间。因此,如果您在XmlNamespaceManager
中指定默认名称空间,则无关紧要,XPath不会使用它。引述从Official XPath Specification有关段落:
的QName在节点测试扩展成使用 命名空间声明从表达式上下文中的扩展名。这与 中的元素类型名称完全相同 扩展方式除了不使用用xmlns声明的默认名称空间外:如果012xxQName没有前缀,则名称空间URI为空 (这个 与扩展属性名称的方式相同)。如果 QName的前缀在 表达式上下文中没有名称空间声明,则会出错。
因此,当您正在阅读的元素属于某个命名空间时,无法避免将命名空间前缀放入XPath语句中。但是,如果您不想将名称空间URI放入代码中,则可以使用XmlDocument
对象返回根元素的URI,在这种情况下,它是您想要的。例如:
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", xml.DocumentElement.NamespaceURI); //Using xml's properties instead of hard-coded URI
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
它怎么样?它是否成功加载文件?如果找到两个站点地图元素?它是否读取任何一个sitemap子元素?我假设这些破折号在元素标签不在实际的xml文件中,对吧? – 2012-07-05 16:06:21
xnList没有被填充。(对不起破折号 - 没有破折号) – Andrew 2012-07-05 16:08:11