I’m loading an XML file, getting the values of some nodes and then setting those values into an object.
The problem is that although I can get into the each node, I can’t get its value: it just returns null. Searching in Google and SO I found several threads saying that usually it is a problem of namespaces. So I set up a namespace on the XML file and in my code to work with it. This is now when things get funny:
- If all the nodes but the last one are prefixed (in my code) with the namespace, all of them gets set except that particular one which gives an ArgumentNullException (
tabladoes not accept nulls on some properties). This seems to be expected behavior. - if I correct that last line and set up the namespace (as it should be), then the exception gets raised at the FIRST node.
This is the XML:
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://daniel.ponticelli.com/ns/dataExport">
<PollInstance>
<Poll_Instance_id>1</Poll_Instance_id>
<POLL_description>Mes 1</POLL_description>
<dt_start>01/09/2012 12:00:00 a.m.</dt_start>
<dt_end>30/09/2012 12:00:00 a.m.</dt_end>
<POLL_status>0</POLL_status>
<dt_created>03/09/2012 09:50:36 a.m.</dt_created>
<dt_updated>03/09/2012 09:50:36 a.m.</dt_updated>
<id_original_clone>0</id_original_clone>
<target_locs>0</target_locs>
<id_poll>1</id_poll>
</PollInstance>
</root>
This is the “wrong” code that has the last element without namespace:
XElement instancia = xml.Descendants().First();
XNamespace ra = "http://daniel.ponticelli.com/ns/dataExport";
tabla.Poll_Instance_id = (int)instancia.Element(ra + "Poll_Instance_id");
tabla.POLL_description = (string)instancia.Element(ra + "POLL_description");
tabla.dt_start = DateTime.Parse((string)instancia.Element(ra + "dt_start"));
tabla.dt_end = DateTime.Parse((string)instancia.Element(ra + "dt_end"));
tabla.POLL_status = (int)instancia.Element(ra + "POLL_status");
tabla.dt_created = DateTime.Parse((string)instancia.Element(ra + "dt_created"));
tabla.dt_updated = DateTime.Parse((string)instancia.Element(ra + "dt_updated"));
tabla.id_original_clone = (int)instancia.Element(ra + "id_original_clone");
tabla.target_locs = (int)instancia.Element(ra + "target_locs");
tabla.id_poll = (int)instancia.Element("id_poll");
The previous code gives the exception on the last line.
Now this is the “correct” code that has all the elements prefixed with the namespace:
XElement instancia = xml.Descendants().First();
XNamespace ra = "http://daniel.ponticelli.com/ns/dataExport";
tabla.Poll_Instance_id = (int)instancia.Element(ra + "Poll_Instance_id");
tabla.POLL_description = (string)instancia.Element(ra + "POLL_description");
tabla.dt_start = DateTime.Parse((string)instancia.Element(ra + "dt_start"));
tabla.dt_end = DateTime.Parse((string)instancia.Element(ra + "dt_end"));
tabla.POLL_status = (int)instancia.Element(ra + "POLL_status");
tabla.dt_created = DateTime.Parse((string)instancia.Element(ra + "dt_created"));
tabla.dt_updated = DateTime.Parse((string)instancia.Element(ra + "dt_updated"));
tabla.id_original_clone = (int)instancia.Element(ra + "id_original_clone");
tabla.target_locs = (int)instancia.Element(ra + "target_locs");
tabla.id_poll = (int)instancia.Element(ra + "id_poll");
This code now gives the exception on the third line! (the one that begins with tabla.Poll_Instance_id). If I set a breakpoint on the “wrong” code just before the last line, I can check in VS that indeed the values are being retrieved from the XML and set on the object tabla as expected; so I don’t know what’s going on.
I have found the solution, thanks to @lazyberezovsky for pointing me to the right direction with the root() thing.
The problem was on the
Descendants()method, which gives me all the descendant nodes; so I was getting the PollInstance node and also thePoll_instance_idand the others. That’s why it breaks on the first line in the “right” code: after processing the first node, it choked on the others.Instead I have to use the
Elements()method which returns only the direct childs; in my case, only thePollInstance.