Reputation:
Here's a sample of the XML I'm working with (retrievable from any wiki's Special:Export/SomePage results):
<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>
I've tried everything I can think of to "jump" directly to the siteinfo node and iterate the results, and nothing works unless I navigate manually through each child node from the root down. I've tried a million variations of the various .Move* and .Select* methods and it seems I'm just bashing my head against a wall, but my current variant looks like this:
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);
This returns no results. What am I doing wrong?
Upvotes: 3
Views: 2765
Reputation: 168958
Welcome to XML namespaces. You need to create a mapping between a prefix and the xmlns
of the root element. For example, this code worked for me:
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);
}
Further reading, in case you are interested: MSDN: XML Namespaces and How They Affect XPath and XSLT.
Upvotes: 9