c# xml element() select element where not defined
i have created the following xml
<Fields xmlns="http://tempuri.org/XMLSchema1.xsd:Fields">
<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 { 开发者_如何学Cget; 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; }
}
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
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.
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();
I know this is a very old reply but i came to this question from google and have found a diffrent solution for my problem.
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.Elements(NameSpace + "Default").Any ? root.Element(NameSpace + "Default").Value : null,
Head = root.Elements(NameSpace + "Head").Any ? root.Element(NameSpace + "Head").Value : null,
}).First();
This worked in my case where following Brians excample gave me the same error as you got.
精彩评论