tags:

views:

515

answers:

3

hi

i have created the following xml

    <Fields xmlns="http://tempuri.org/XMLSchema1.xsd:Fields"&gt;
         <Field Name="ServiceProviderName">    
               <ID>0</ID>      
         </Field>   
         <Field Name="TransactionNumber">    
               <ID>1</ID>
               <Padding Length="8" PadChar="0"/>
               <MaxLength>10</MaxLength>
         </Field>   
         <Field Name="Sim">    
              <ID>2</ID>
              <Head>8927</Head>
              <Padding Length="15" PadChar="0"/>   
         </Field> 
     </Fields>

and i am trying to assign this to an object using linq. i have defined an object called N2NField

var xe = (from root in xdb.Descendants(NameSpace + "Field") 
where root.Attribute("Name").Value.Equals(Name)                                      
select new N2NField
{
            Name = root.Attribute("Name").Value,
            ID = int.Parse(root.Element(NameSpace+"ID").Value),
            Default = root.Element(NameSpace + "Default").Value,
            Head = root.Element(NameSpace + "Head").Value,
            Tail = root.Element(NameSpace + "Tail").Value,
            MinLength = int.Parse(root.Element(NameSpace + "MinLength").Value),
            MaxLength = int.Parse(root.Element(NameSpace + "MaxLength").Value)                                           

                                       }).First();

i am getting an object not set to an instance of object error when searching for Name="Sim". I understand that this is happening because in the xml fields like Tail, MinLength, MaxLength, etc have not been set. This is logical because my xsd defines those minoccurrences are set to 0. in theory there will be some fields in the xml that have some fields while not having others and having mandatory fields.

is there any way to check to see if the fields exist and if they don't assign the object N2NField values as null for those properties? i don't want to be forced to make all the fields mandatory in the xsd. any ideas?

Edit - N2N Field Class

public class N2NField { 
   public string Name { get; set; } 
   public int ID { get; set; } 
   public string Default { get; set; } 
   public string Head { get; set; } 
   public string Tail { get; set; } 
   public int MinLength { get; set; } 
   public int MaxLength { get; set; } 
 }
A: 

Seems you don't have some nodes in your XML; note I removed .Value property and added a cast to string.

var xe = (from root in xdb.Descendants(NameSpace + "Field")
          where root.Attribute("Name").Value.Equals("Sim")
          select new N2NField
          {
              Name    = (string)root.Attribute("Name"),
              ID      = int.Parse((string)root.Element(NameSpace + "ID") ?? "0"),
              Default = (string)root.Element(NameSpace + "Default"),
              Head    = (string)root.Element(NameSpace + "Head"),
              Tail    = (string)root.Element(NameSpace + "Tail"),
              MinLength = int.Parse((string)root.Element(NameSpace + "MinLength") ?? "0"),
              MaxLength = int.Parse((string)root.Element(NameSpace + "MaxLength") ?? "0")
          }).First();

HTH

Rubens Farias
This is correct. some of the nodes are illogical to have for some of the fields at a design level. i can add the fields and have some default values but i want to avoid that.
Kamal
A: 

i've been messing around with this idea and it seems to be working for me

XElement xdb = XElement.Load(XMLPath);
            XNamespace NameSpace = xdb.Name.Namespace;

            var xe = (from root in xdb.Descendants(NameSpace + "Field")
                           where root.Attribute("Name").Value.Equals(Name)                                       
                           select new N2NField
                                       {
                                           Name = root.Attribute("Name").Value,
                                           ID = int.Parse(root.Element(NameSpace+"ID").Value),
                                           Default = root.Descendants(NameSpace + "Default").Any() ? root.Element(NameSpace + "Default").Value : null,
                                           Head = root.Descendants(NameSpace+"Head").Any() ? root.Element(NameSpace + "Head").Value : null,
                                           Tail = root.Descendants(NameSpace+"Tail").Any() ? root.Element(NameSpace + "Tail").Value : null,
                                           MinLength = root.Descendants(NameSpace+"MinLength").Any()  ? int.Parse(root.Element(NameSpace + "MinLength").Value) : -1,
                                           MaxLength = root.Descendants(NameSpace+"MaxLength").Any() ? int.Parse(root.Element(NameSpace + "MaxLength").Value) : -1                                           

                                       }
                                       ).First();

by checking if the element exists first with Descendants().Any() it allows me to assign a default value at a code level if the node doesn't exist.

Kamal
A: 

This is more efficient than using the Descendants().Any() method. This just checks if the one that you are looking for to see if it is null and if it isn't assigns the value.

var xe = (from root in xdb.Descendants(NameSpace + "Field")
          where root.Attribute("Name").Value.Equals(Name)
          select new N2NField
          {
              Name = root.Attribute("Name").Value,
              ID = int.Parse(root.Element(NameSpace + "ID").Value),
              Default = root.Element(NameSpace + "Default") == null ? root.Element(NameSpace + "Default").Value : null,
              Head = root.Element(NameSpace + "Head") == null ? root.Element(NameSpace + "Head").Value : null,
              Tail = root.Element(NameSpace + "Tail") == null ? root.Element(NameSpace + "Tail").Value : null,
              MinLength = root.Element(NameSpace + "MinLength") == null ? int.Parse(root.Element(NameSpace + "MinLength").Value) : -1,
              MaxLength = root.Element(NameSpace + "MaxLength") == null ? int.Parse(root.Element(NameSpace + "MaxLength").Value) : -1

          }).First();
Brian ONeil
Hi Brian,I had actually tried that. but i was still getting the object not set to an instance of an object. i believe that (for example) root.Element(NameSpace + "Tail") does not even resolve to null if it does not exist (which i assumed it would).
Kamal
it worked for me... I will double check it, but I did try it before I posted it. Are you sure that you weren't checking .Value and not just the result from the Element call?
Brian ONeil
Thanks for the feedback.i've just triple checked this :) exampleDefault = root.Element(NameSpace + "Default") == null ? root.Element(NameSpace + "Default").Value : null,still throws error when i don't have a Default node.
Kamal