3

I have seen a couple of examples on here where Xpath is used in conjunction with XmlDocument to get a specific attribute from an XmlDocument Node.... Example

Console.WriteLine(xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/@name").Value.ToString());

For some reason I am getting a "Object reference not set to an instance of an object." exception. Whenever I run across that particular line of code. I have a little test app that I have set up to test out different things before I put them into my main project...

Here is the code for that...

namespace ReadXml
{
    class Program
    {
        static void Main(string[] args)
        {
            //string fulXmlPath =     System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/templateExample.xml");
            XDocument xDocument = XDocument.Load("C:\\Users\\derekww\\Documents\\XML Documents\\templateExample.xml");
            XElement elem = xDocument.Element("dataTemplateSpecification"); ;
            XmlDocument xmlDocument = new XmlDocument();
            StreamReader file = new StreamReader("C:\\Users\\derekww\\Documents\\XML Documents\\templateExample.xml");

            xmlDocument.Load(file);

            //XmlDocument theDoc = new XmlDocument();
            //using (var xmlReader = xDocument.CreateReader())
            //{
            //    xmlDocument.Load(xmlReader);
            //}

            //Console.WriteLine(elem.ToString());
            XmlNode xNode = xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element");
            Console.WriteLine("WORK PLEASE!!!! {0}", xNode.Value.ToString());
            //Console.WriteLine(xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/@name").Value.ToString());
            //Console.WriteLine("This better Work>>>> {0}", xmlDocument.Attributes["/dataTemplateSpecification/templates/template/elements/element/@name"].Value);
            Console.ReadLine();
            //Console.WriteLine("This better Work>>>> {0}", xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/@name").Value);
            //foreach (String AttVal in xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/@name").Value)
            {
                //Console.WriteLine("This better Work>>>> {0}", AttVal);
            }
        }
    }
}

Here is part of the XML that I used...

    <?xml version="1.0" encoding="utf-8"?>
    <dataTemplateSpecification id="id1" name="name1" xmlns="http://EADIS.upmc.com      /DataTemplateSpecification.xsd">
      <description xmlns="">
        <html>text</html>
      </description>
      <templates xmlns="">
        <template>
          <elements>
            <element id="element0" name="PatientId" display="Patient ID"  dataType="String" value="0101010111111" visable="false" readOnly="true">
              <validation>
                <rules>
                  <rule id="0" test="#element0.value == ''">
                    <fail>
                      <html><b>Patient ID is null, value must be present</b></html>
                    </fail>
                  </rule>
                </rules>
              </validation>
            </element>
           </elements>
          </template>
         <templates>

I just showed you the part that you need to understand the xml structure. I assure you that it is well formed. I think I asked this question before but somehow or the other it didn't get posted (maybe I forgot, who knows). Any help with this would be greatly appreciated. If I come up with a reason for why it isn't working I will be sure to let you guys know.

Thank You.

VMAtm
  • 27,943
  • 17
  • 79
  • 125
SoftwareSavant
  • 9,467
  • 27
  • 121
  • 195
  • 5
    Remove the unnecessary profanity from your code, indent your code samples by 4 spaces to make them show correctly, and read up on the [XmlNamespaceManager](http://msdn.microsoft.com/en-us/library/system.xml.xmlnamespacemanager.aspx) – Tomalak Jul 05 '11 at 12:52
  • 2
    possible duplicate of [Using Xpath With Default Namespace in C#](http://stackoverflow.com/questions/585812/using-xpath-with-default-namespace-in-c) – Tomalak Jul 05 '11 at 12:56
  • Why don't you stick to Linq to XML? I think it's much more easier and more straightforward. – Saeed Neamati Jul 05 '11 at 13:10
  • 2
    Ok. Just figure it out. Thanks Tomalak. After a little bit of research, you apparently have to add a namspaceManager to your Xpath querries. To do that you need to add a XmlNameSpaceManger, a prefix, and so on. Thanks again. – SoftwareSavant Jul 05 '11 at 13:26
  • That is what I would like to do Saeed. Just use Xdoc and some Linq to XML. Short answer, office politics. One of my bosses likes linq, the other Despises it for various reason. This project is for the second boss. Both Good guys, just different philosophies I suppose. I am just glad a learned a new way to do the same thing. Thanks again for the help. – SoftwareSavant Jul 05 '11 at 13:28
  • @Dmain: +1 for figuring it out on your own. If you post the relevant part of your fixed code as an answer, I'd vote that up as well. – Tomalak Jul 05 '11 at 13:32
  • I thought I figured it out. I just realized I did not. I am not getting the results that I was expecting. I Am not returning any nodes in my xmlNodeList. I don't understand what is going on. Let me ask you a question, if there are any stray xmlns attributes anywhere in the .xml file, will that affect the namespace manager in anyway. Even if the value of the XMLNS is null? – SoftwareSavant Jul 06 '11 at 13:27

2 Answers2

7

Why can't you use this XPath:

xmlDocument.SelectSingleNode("//templates/template/elements/element/@name").Value
VMAtm
  • 27,943
  • 17
  • 79
  • 125
  • Because the XML contains a default namespace and this XPath expression will not return anything. ;) – Tomalak Jul 05 '11 at 13:31
  • @Tomalak Did you try this before saying that? It works for me for this xml. – VMAtm Jul 05 '11 at 13:36
  • Oh, I overlooked the stray `xmlns=""`. My fault. (and +1, then) – Tomalak Jul 05 '11 at 13:42
  • I just looked at a coworkers xmlDocument.SelectSingleNode() call. He doesn't set up a namespace manager either and his works like flying colors. Something is missing here. Perhaps I may have discovered a flaw in one Microsofts Libraries. – SoftwareSavant Jul 06 '11 at 12:30
1

You need to specify the namespace of the XML file in your code.
See here for more info: How to select xml root node when root node has attribute?

Community
  • 1
  • 1
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443