1

I am getting some XML data in the form of a string from a database. The data is saved as ntext in the database.

Getting the data from the database is not a problem. The problem is later, when I want to handle the data in the xml. I load a string into an xDocument.

I want to get the Owner value at first. But I get a nullreference exception, meaning that I do not write the correct Xpath I assume.

Writing "./Owner" does not work. Writing "/./Owner" does not work I then get an XML exception.

I started out with XMLDocument but think I ran into a namespace problem. Started reading and looks like using xDocument is better. As you also can see by my code, I have tried getting the Owner value in two ways, both fail.

My XML looks a bit like this:

    <Container xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="DM">
<IsConsigned>false</IsConsigned>
<LockState>Unlocked</LockState>
<SourceType i:nil="true" />
<Id>04216194-4f62-47ee-ab21-c1053d01bf1e</Id>
<Owner>IN</Owner>
<Created>2012-08-21T09:29:10.528321+02:00</Created>
</Container>

And my code:

      class Program
{
   static SqlConnection conn = new SqlConnection();
   static XDocument xml = new XDocument();

    static void Main(string[] args)
    {
        using (conn)
        {
            conn.ConnectionString = Properties.Settings.Default.connectionString;
            //connection.Open();
            conn.Open();
            SqlDataReader reader = GetDataFromDatabase();

            if (reader.HasRows)
            {

                while (reader.Read())
                {
                    string xmlFile = reader.GetSqlString(0).ToString();
                    HandleData(xmlFile);
                }
            }
            else
            {
                Console.WriteLine("No rows found.");
            }
            reader.Close();
        }
    }

    public static void HandleData(string xmlIn)
    {

        xml = XDocument.Parse(xmlIn);
        XElement xmlElement = xml.Root;
        string test1 = xml.Element("Owner").Value.ToString();
        string test = xmlElement.Element("Owner").Value.ToString();
    }

    }
Jason Evans
  • 28,906
  • 14
  • 90
  • 154
Dreas89
  • 27
  • 7

2 Answers2

2

That wasn't a problem of using XmlDocument or XDocument. Your XML has default namespace, a namespace declared without prefix, here :

xmlns="DM"

contrasts with the one with prefix i here: xmlns:i="http://www.w3.org/2001/XMLSchema-instance". Note that not only element where default namespace declared is in that namespace, but all descendant elements inherit ancestor default namespace implicitly, unless otherwise specified (using explicit namespace prefix or local default namespace that point to different namespace uri).

You can use combination of "XNamespace"+"element's local name" to form a qualified-name for referencing element in namespace, for example :

var xmlIn = @"<Container xmlns:i='http://www.w3.org/2001/XMLSchema-instance' xmlns='DM'>
<IsConsigned>false</IsConsigned>
<LockState>Unlocked</LockState>
<SourceType i:nil='true' />
<Id>04216194-4f62-47ee-ab21-c1053d01bf1e</Id>
<Owner>IN</Owner>
<Created>2012-08-21T09:29:10.528321+02:00</Created>
</Container>";
var xml = XDocument.Parse(xmlIn);
XNamespace d = "DM";
string owner = xml.Root.Element(d+"Owner").Value;
Console.WriteLine(owner);
string id = xml.Root.Element(d+"Id").Value;
Console.WriteLine(id);

Dotnetfiddle Demo

output :

IN
04216194-4f62-47ee-ab21-c1053d01bf1e

Side notes:

  • Element() doesn't recognize XPath expression, it accepts XName parameter instead.
  • XElement.Value property is a string already, no need to call ToString() on it.
  • Similar case for reference, if you need to use XPath with XDocument later : Use XPath with XML namespace
Community
  • 1
  • 1
har07
  • 88,338
  • 12
  • 84
  • 137
  • Thanks! That did it. I understand that I have some reading to do regarding namespaces. As you see in my first post, I ran into namespace problems with XMLDocument, but did not understand how I could solve it. With your help I now am on the right path anyway. I will read more about namespaces and prefix. Thanks yet again! – Dreas89 Jul 21 '15 at 08:19
0

Please read more about XPath at http://www.w3schools.com/xpath/default.asp.

Your solution found here:https://dotnetfiddle.net/Aflm8t

Lior Dadon
  • 233
  • 2
  • 10
  • How can reading up on Xpath help me in this matter more exactly? Yes, my first try on getting the right value does not work because I do not write "Container/Owner". Just a test, the one below, using the xml.root(container, right?) and then going to "Owner" should be the right Xpath if I am not mistaken? You also in your code assign the Namespace used in the XML to the instance, I assume? Where is the glitch, Namespace? Just adding "Using XML.XPath" and then the xpath does not work. Therefore the error should be somewhere else. I assume anyway. – Dreas89 Jul 21 '15 at 08:04