3

I know this question has been asked in a similar fashion before, but I can't seem to get this working.

I have some xml:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
    <Research xmlns="http://www.rixml.org/2005/3/RIXML" xmlns:xalan="http://xml.apache.org/xalan" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" createDateTime="2011-03-29T15:41:48Z" language="eng" researchID="MusiJvs3008">
    <Product productID="MusiJvs3008">
    <StatusInfo currentStatusIndicator="Yes" statusDateTime="2011-03-29T15:41:48Z" statusType="Published" />
    <Source>
    <Organization type="SellSideFirm" primaryIndicator="Yes">
    <OrganizationID idType="Reuters">9999</OrganizationID> 

And I'm trying to read values using xpath:

XPathDocument xmldoc = new XPathDocument(xmlFile); 
XPathNavigator nav = xmldoc.CreateNavigator(); 
XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable);
nsMgr.AddNamespace(string.Empty, "http://www.rixml.org/2005/3/RIXML"); 
XPathNavigator result = nav.SelectSingleNode("/Research", nsMgr); // <-- Returns null!

But even a simple select of the root node returns null! I am sure I have something wrong with my namespace. Can someone please help?

Ideally I want simple lines that will let me select values from the xml file, i.e.

String a = xmlDoc.SelectSingleNode(@"/Research/Product/Content/Title").Value;

BTW, I have no (direct) control over the XML file content.

casperOne
  • 73,706
  • 19
  • 184
  • 253
Ryan
  • 3,924
  • 6
  • 46
  • 69

3 Answers3

5

I don't believe you can use an empty namespace alias and have it used automatically by the XPath expression. As soon as you use an actual alias, it should work though. This test is fine, for example:

using System;
using System.Xml;
using System.Xml.XPath;

class Test
{
    static void Main() 
    {
        string xmlFile = "test.xml";
        XPathDocument xmldoc = new XPathDocument(xmlFile); 
        XPathNavigator nav = xmldoc.CreateNavigator(); 
        XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable);
        nsMgr.AddNamespace("x", "http://www.rixml.org/2005/3/RIXML"); 
        XPathNavigator result = nav.SelectSingleNode("/x:Research", nsMgr);
        Console.WriteLine(result);
    }
}

Do you have to use XPath and XPathDocument, by the way? I tend to find that LINQ to XML is a much more pleasant API, particularly when it comes to namespaces. If you're using .NET 3.5 and you have no particular requirement to use XPath, I'd suggest you check it out.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Great answer, thanks a lot for your help. I woud like to use LINQ, but I get annoyed by the impact on debugging, i.e. any change to a lamda expression means you have to restart the entire process. Thanks again! Ryan – Ryan Mar 30 '11 at 17:01
  • @Ryan: Do you spend a lot of time in the debugger? I very rarely use edit and continue - I just recompile and run the unit tests again. – Jon Skeet Mar 30 '11 at 17:04
  • Always! I find stop/start very slow for development, especially if it's an ASP app. – Ryan Apr 05 '11 at 06:51
  • 1
    @Ryan: So what's your unit test coverage like? Even in a web application, *most* of your significant code should be testable... and running unit tests should be quick. – Jon Skeet Apr 05 '11 at 06:52
  • @JonSkeet I tried clearing out the field and then re-populate but it's making the entire node disappear: http://stackoverflow.com/questions/31081361/why-is-there-an-error-when-clearing-out-a-field-and-adding-text. Please help. – SearchForKnowledge Jun 26 '15 at 20:33
3

Make the following changes

nsMgr.AddNamespace("x", "http://www.rixml.org/2005/3/RIXML"); 
XPathNavigator result = nav.SelectSingleNode("/x:Research", nsMgr);
BENBUN Coder
  • 4,801
  • 7
  • 52
  • 89
0

i could post, and answer my own question, for the native equivalent of this code. Instead i'll just add it as an answer to the end.

When using the native IXMLDOMDocument (version 6) object:

//Give the default namespace as alias of "x"
document.setProperty("SelectionNamespaces","xmlns:x='http://www.rixml.org/2005/3/RIXML'");

//Query for the nodes we want
document.selectSingleNode("/x:Research");

Bonus Question: Why, oh why, does no Xml Document object model query the default namespace when no namespace is specified... sigh

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219