XPathNavigator帮助

3
以下是我正在处理的XML示例(可从任何维基的Special:Export/SomePage结果中检索):
<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.4/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.4/ http://www.mediawiki.org/xml/export-0.4.xsd" version="0.4" xml:lang="en"> 
  <siteinfo> 
    <sitename>Wikipedia</sitename> 
    <base>http://en.wikipedia.org/wiki/Main_Page</base> 
    <generator>MediaWiki 1.16wmf4</generator> 
    <case>first-letter</case> 
    <namespaces> 
      <namespace key="-2" case="first-letter">Media</namespace> 
      <namespace key="-1" case="first-letter">Special</namespace> 
      <namespace key="0" case="first-letter" /> 
      ...
    </namespaces> 
  </siteinfo> 
</mediawiki> 

我已尝试了所有能想到的方法来直接“跳转”到siteinfo节点并迭代结果,但除非我手动浏览从根节点向下的每个子节点,否则没有任何效果。我尝试了各种各样的.Move*和.Select*方法的变体,似乎只是白费力气,但我目前的变体看起来像这样:

StringReader strr = new StringReader(_rawData);
XPathDocument xd = new XPathDocument(XmlReader.Create(strr, Bot.XmlReaderSettings));
XPathNavigator xn = xd.CreateNavigator();
XPathNodeIterator xni = xn.Select("/mediawiki/siteinfo");
foreach (XPathNavigator nav in xni)
    Console.WriteLine(nav.LocalName);

这个操作没有返回任何结果,我做错了什么吗?
1个回答

9
欢迎使用XML命名空间。您需要创建一个前缀和根元素的xmlns之间的映射。例如,以下代码适用于我:
using (var r = File.OpenText("test.xml")) {
    XPathDocument xd = new XPathDocument(XmlReader.Create(r));
    XPathNavigator xn = xd.CreateNavigator();

    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xn.NameTable);
    nsmgr.AddNamespace("mw", "http://www.mediawiki.org/xml/export-0.4/");

    XPathNodeIterator xni = xn.Select("/mw:mediawiki/mw:siteinfo", nsmgr);

    foreach (XPathNavigator nav in xni)
        Console.WriteLine(nav.Name);
}

如果您感兴趣,可以进一步阅读以下内容:MSDN:XML命名空间及其对XPath和XSLT的影响


为了获得额外的奖励分数,是否可以通过XPathNavigator确定命名空间的URL,还是应该只使用正则表达式,因为我已经有了字符串? - user502255
没关系,我自己解决了:xn.MoveToFirstChild(); nsmgr.AddNamespace("mw", xn.NamespaceURI); - user502255

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接