1

这是我的示例 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>

如何在 C# 中使用 linq 获取基于 id 的对话列表。例如,如果我想获取 id 为“A100”的对话,该对话具有指向基于 ReplyToid 的其他对话的链接。

4

2 回答 2

2

编辑: 由于您的澄清,我已经重写了我的答案。

构建对话树

  1. 用于XElement从您的 xml 文件加载根元素及其子元素:

    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:第一阶段
      *->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

我必须再包含一个函数来进行递归搜索:-)。

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 回答