我创建了以下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>
我正在尝试使用linq将其分配给对象。我已经定义了一个名为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();
我在搜索Name =“Sim”时得到一个未设置为对象错误实例的对象。我知道这种情况正在发生,因为在像Tail,MinLength,MaxLength等的xml字段中还没有设置。这是合乎逻辑的,因为我的xsd定义了那些minoccurrences设置为0.理论上,xml中会有一些字段包含一些字段而没有其他字段且具有必填字段。
有没有办法检查字段是否存在以及它们是否没有为这些属性将对象N2NField值指定为null?我不想被迫在xsd中强制要求所有字段。任何想法?
编辑 - N2N字段类
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; }
}
答案 0 :(得分:2)
似乎你的XML中没有一些节点;请注意我删除了.Value
属性并添加了一个强制转换为字符串。
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
答案 1 :(得分:0)
我一直在搞乱这个想法,它似乎对我有用
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();
通过检查元素是否首先存在于Descendants()。Any()它允许我在代码级别分配默认值(如果节点不存在)。
答案 2 :(得分:0)
这比使用Descendants()。Any()方法更有效。这只是检查你正在寻找的那个是否为空,如果它没有赋值。
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();
答案 3 :(得分:0)
我知道这是一个非常古老的回复,但我从谷歌那里得到了这个问题,并为我的问题找到了一个不同的解决方案。
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();
这适用于我的情况,其中跟随Brians的例子给了我同样的错误。