1

this is my sample xml.

<Messages>
  <Conversation>
    <id>Z100</id>
    <ReplyToId></ReplyToId>
    <Message>Topic</Message>
  </Conversation>
  <Conversation>
    <id>A100</id>
    <ReplyToId></ReplyToId>
    <Message>This is a test</Message>
  </Conversation>
  <Conversation>
    <id>M100</id>
    <ReplyToId>A100</ReplyToId>
    <Message>What kind of test</Message>
  </Conversation>
  <Conversation>
    <id>A200</id>
    <ReplyToId>M100</ReplyToId>
    <Message>Stage 1</Message>
  </Conversation>
  <Conversation>
    <id>M200</id>
    <ReplyToId>A200</ReplyToId>
    <Message>Test result for </Message>
  </Conversation>
</Messages>

How to get the conversation list based on id using linq in C#. Say for example, If i want to get the conversation for id "A100" which has a link to other conversation based on ReplyToid.

4

2 に答える 2

2

編集: あなたの説明のために、私は私の答えを書き直しました。

会話ツリーの構築

  1. xmlファイルからルート要素とその子をロードするために使用XElementします。

    var root = XElement.Load(@"path\to\your.xml"); 
    // Alternatively, XElement.Parse(stringContainingXML);
    
  2. 要素を会話に変換します(会話クラスは以下に示されています):

    var conversations = (from element in root.Elements()
                         select Conversation.FromXElement(element)).ToList();
    // ToList prevents multiple iteration of the IEnumerable
    
  3. 各会話に返信を追加します。

    foreach (var conversation in conversations)
    {
        conversation.Replies.AddRange( 
        conversations.Where(reply => reply.ReplyToId == conversation.Id));
    }
    
  4. 必要に応じて、トップレベルから返信を削除します。

    conversations.RemoveAll(x => !string.IsNullOrEmpty(x.ReplyToId));
    
  5. オプションで、 IDで単一の会話を取得するには:

    Conversation singleConversation = conversations.Single(x => x.Id == "A100");
    

結果

Z100:トピック
A100:これはテストです
*-> M100:どのようなテスト
   *-> A200:ステージ1
      *-> M200:のテスト結果

会話ヘルパークラス

public class Conversation
{
    public string Id { get; private set; }
    public string ReplyToId { get; private set; }
    public string Message { get; private set; }
    public readonly List<Conversation> Replies = new List<Conversation>();

    public static Conversation FromXElement(XElement source)
    {
        return new Conversation
        {
            Id = (string)source.Element("id"),
            ReplyToId = (string)source.Element("ReplyToId"),
            Message = (string)source.Element("Message")
        };
    }     
}
于 2012-09-06T21:36:20.740 に答える
0

再帰検索を行うには、もう1つの関数を含める必要がありました:-)。

public IEnumerable<Conversation> GetReplies() {
  yield return this;

  if (Replies != null) {
    foreach (var item in Replies
                          .Where(s => s != null)
                          .SelectMany(x => x.GetReplies())) {
      yield return item;
    }
  }
}
于 2012-09-07T17:57:42.367 に答える