1

xmlを定義するクラスと、候補を定義する別のクラスと、クラス候補のリストである別のクラスがあります。

XMLにあるノードの数に応じてリストを動的に作成しようとしています。

私はすべての種類のバリエーションを試しましたが、ノード候補がすべての情報を取得するまで何も機能しませんでしたが、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;
}
4

2 に答える 2

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 に答える
0

質問を整理してくれてありがとう - 水平方向にスクロールしなければならないのは少し悪夢です (編集して表示します)。

とにかく-あなたの主な問題は、候補者ノードを選択するビットであるようです:

CandidateList = (from i in input.Root.Element("Candidates").Elements("Candidate") 

CandidateList問題は、linq クエリがインスタンスを生成しないことです。これを行う 1 つの方法は、範囲コンストラクターを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>CandidateListfromCandidates/CandidateRequests/Requestr

Candidate最後に、オブジェクトへのすべてのプロパティの割り当ては元のものであり、それらを(内部の Linq ステートメントの生成物)rに変更する必要があります。i

于 2012-07-17T08:02:28.557 に答える