简体   繁体   中英

Null reference exception - XDocument using Element and XPath

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();
    }

    }

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM