1

我有一个定义 xml 的类和另一个定义候选者的类和另一个类,它是类候选者的列表。

我正在尝试根据 xml 中的节点数动态创建列表。

我尝试了各种变体,但没有任何效果,直到节点候选人我得到了所有信息,但候选人列表一直为空。

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;
}
4

2 回答 2

0

感谢您整理问题 - 必须水平滚动是一场噩梦(将编辑显示)。

无论如何-您的主要问题似乎是您选择候选人节点的位置:

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>. CandidateList请注意,我已经更改了from; 因为你想要Candidates/Candidate当前的节点Requests/Request,它由r.

最后 - 您对对象的所有属性分配Candidate都来自r- 您需要将它们更改为i(内部 Linq 语句的产物)。

于 2012-07-17T08:02:28.557 回答
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;
}
于 2012-07-17T08:24:22.367 回答