我有一个定义xml的类和另一个定义候选的类,另一个类是候选类的列表。
我正在尝试根据xml中的节点数动态创建列表。
我尝试了所有类型的变化并没有任何效果,直到节点Candidates我获得了所有信息,但CandidateList始终为null。
public class Candidate
{
}
public class CandidateList : List<Candidate>
{
}
public class Request
{
public CandidateList CandidateList { get; set; }
}
<?xml version="1.0" encoding="utf-8"?>
<Requests>
<Request>
<MidaClientID>1040</MidaClientID>
<!--elided other elements-->
<OrderDescription></OrderDescription>
<Candidates>
<Candidate>
<QuestNum>6</QuestNum>
<!--elided other elements-->
<EventNum>012</EventNum>
</Candidate>
<Candidate>
<QuestNum>6</QuestNum>
<!--elided other elements-->
<EventNum>012</EventNum>
</Candidate>
</Candidates>
</Request>
</Requests>
try
{
IEnumerable<Request> req = from r in input.Descendants("Request")
select new Request()
{
MidaClientID = (int)r.Element("MidaClientID") != 0 ? (int)r.Element("MidaClientID") : 0,
Password = (string)r.Element("MidaClientPassword") != null ? (string)r.Element("MidaClientPassword") : string.Empty,
ClientNum = (int)r.Element("ClientNum") != 0 ? (int)r.Element("ClientNum") : 0,
ClientName = (string)r.Element("ClientName") != null ? (string)r.Element("ClientName") : string.Empty,
ContactNum = (int)r.Element("ContactNum") != 0 ? (int)r.Element("ContactNum") : 0,
ContactFirstName = (string)r.Element("ContactFirstName") != null ? (string)r.Element("ContactFirstName") : string.Empty,
ContactLastName = (string)r.Element("ContactLastName") != null ? (string)r.Element("ContactLastName") : string.Empty,
ContactEmail = (string)r.Element("ContactEmail") != null ? (string)r.Element("ContactEmail") : "",
OrderID = (int)r.Element("OrderID") != 0 ? (int)r.Element("OrderID") : 0,
OrderDesc = (string)r.Element("OrderDescription") != null ? (string)r.Element("OrderDescription") : "",
CandidateList = (from i in input.Root.Element("Candidates").Elements("Candidate")
select new Candidate()
{
QuestNum = (int)r.Element("QuestNum") != 0 ? (int)r.Element("QuestNum") : 0,
CandNum = (int)r.Element("CandNum") != 0 ? (int)r.Element("CandNum") : 0,
EventNum = (int)r.Element("EventNum") != 0 ? (int)r.Element("EventNum") : 0,
EventDate = (string)(r.Element("EventDate")) == string.Empty ?
DateTime.Today : (DateTime)(r.Element("EventDate")),
EventTime = (string)(r.Element("EventTime")) == string.Empty ?
DateTime.Now : (DateTime)(r.Element("EventTime")),
CandFirstName = (string)r.Element("CandFirstName") != null ? (string)r.Element("CandFirstName") : string.Empty,
CandLastName = (string)r.Element("CandLastName") != null ? (string)r.Element("CandLastName") : string.Empty,
CandPhone1 = (string)r.Element("CandPhone1") != null ? (string)r.Element("CandPhone1") : string.Empty,
CandPhone2 = (string)r.Element("CandPhone2") != null ? (string)r.Element("CandPhone2") : string.Empty,
CandPhone3 = (string)r.Element("CandPhone3") != null ? (string)r.Element("CandPhone3") : string.Empty,
CandAttach1 = (string)r.Element("CandAttach1") != null ? (string)r.Element("CandAttach1") : string.Empty,
CandAttach2 = (string)r.Element("CandAttach2") != null ? (string)r.Element("CandAttach2") : string.Empty,
CandAttach3 = (string)r.Element("CandAttach3") != null ? (string)r.Element("CandAttach3") : string.Empty
}) as CandidateList
};
return req.ToList();
}
catch (Exception ex)
{
throw ex;
}
答案 0 :(得分:0)
感谢您整理问题 - 不得不横向滚动有点噩梦(将编辑显示)。
无论如何 - 您的主要问题似乎是您选择Candidates节点的位置:
CandidateList = (from i in input.Root.Element("Candidates").Elements("Candidate")
问题是linq查询不会产生CandidateList
实例。一种方法是将范围构造函数添加到CandidateList
类型并将linq查询提供给它。另外 - 我认为input.Root
是错误的。
public class CandidateList : List<Candidate>{
public CandidateList() {}
public CandidateList(IEnumerable<Candidate> range) : base(range) {}
}
//.. in 'new Request{' block
select new Candidate {
// ... other members elided
CandidateList = new CandidateList(
(from i in r.Element("Candidates").Elements("Candidate")
select new Candidate()
{
//...all the Candidate members
})
) //<-- end of the constructor call
}
在将查询移到构造函数中之后,您还需要从该查询的末尾删除as CandidateList
,否则您将获得一个空的CandidateList,或者可能从{ArgumentNullException
获取List<T>
{1}}基类CandidateList
。请注意,我已更改from
;因为您希望当前Candidates/Candidate
的{{1}}个节点由Requests/Request
提供。
最后 - r
对象的所有属性分配都来自Candidate
- 您需要将这些属性更改为r
(内部Linq语句的产品)。
答案 1 :(得分:0)
您需要显式实例化CandidateList
属性。
var doc = XElement.Load(@"path-to-xml");
var result = doc.Descendants("Request")
.Select(RequestSelector);
private Request RequestSelector(XElement elem)
{
var request = new Request();
// Fill properties here
request.Candidates = new CandidateList();
request.Candidates.AddRange(elem.Descendants("Candidate").Select(CandidateSelector));
return request;
}
private Candidate CandidateSelector(XElement elem)
{
var candidate = new Candidate();
candidate.CandFirstName = elem.Element("CandFirstName").Value;
// Fill other properties here
return candidate;
}