XDOC为查询Select语句(Select statement for xdoc query )

2019-09-16 18:46发布

我想一个子类别添加到我的XML语句的消息有没有一种方法,我可以做到这一点GroupMessages -> Message -> GroupMessage

        var groups = xDoc.Descendants("Group")
            .Select(n => new
            {
                GroupName = n.Element("GroupName").Value,
                GroupHeader = n.Element("GroupHeader").Value,
                TimeCreated = DateTime.Parse(n.Element("TimeAdded").Value),
                Tags = n.Element("Tags").Value, 
                Messages = n.Element("GroupMessages").Value
                //line above
            })
            .ToList();
        dataGrid2.ItemsSource = groups;

在我的方法GroupMessages同时包含邮件ID和GroupMessage并且它无论是在一个容器内,我的DataGrid上市。 所以,我想这一点,但它列出了什么:

 Messages = n.Descendants("GroupMessages").Select(nd => nd.Element("GroupMessage").Value)

我的XML看起来是这样的:

<Group>
<TimeAdded>2012-04-27T10:23:50.7153613+01:00</TimeAdded>
<GroupName>Group</GroupName>
<GroupHeader>Header</GroupHeader>
<GroupMessages>
<Message>
<MessageID>1</MessageID>
<GroupMessage>Message</GroupMessage>
<MessageGroup/>
</Message>
</GroupMessages>
</Group>

我也曾尝试:

Messages = n.Descendants("GroupMessages").Select(nd => nd.Descendants("Message").Select(nde => nde.Element("GroupMessage").Value))

无济于事?

更新:

    private void ListGroups_Click(object sender, RoutedEventArgs e)
    {
        string uriGroup = "http://localhost:8000/Service/Group";
        XDocument xDoc = XDocument.Load(uriGroup);
        var groups = xDoc.Descendants("Group")
                    .Select(n => new
        {
            GroupName = n.Element("GroupName").Value,
            GroupHeader = n.Element("GroupHeader").Value,
            TimeCreated = n.Element("TimeAdded").Value,
            Tags = n.Element("Tags").Value,
            Messages = n.Element("GroupMessages").Descendants("Message").Select(nd => new
            {
                //Id = nd.Element("MessageID").Value,
                Message = nd.Element("GroupMessage").Value
            }).FirstOrDefault()
        })
        .ToList();
        dataGrid2.ItemsSource = groups;
    }

Unfortunatley这种方法显示DataGrid中的细胞内“收集”。 如果我尝试ToArray的,它会显示在细胞内的数组消息。 是否有实际显示GroupMessage的方法吗? 不知道你如何设置一个DataGrid的子元素?

Answer 1:

在最基本的层面上,你可以做到这一点得到一个消息,(第一个):

var groups = from grp in xDoc.Descendants("Group")
             select new { 
                GroupName = grp.Element("GroupName").Value,
                GroupHeader = grp.Element("GroupHeader").Value,
                TimeCreated = DateTime.Parse(grp.Element("TimeAdded").Value),
                Message = grp.Element("GroupMessages").Element("Message").Element("GroupMessage").Value
             };

不过,我认为你要Messages能够同时与ID和消息的消息列表。 在这种情况下,可以这样考虑:

var groups = from grp in xDoc.Descendants("Group")
             select new { 
                GroupName = grp.Element("GroupName").Value,
                GroupHeader = grp.Element("GroupHeader").Value,
                TimeCreated = DateTime.Parse(grp.Element("TimeAdded").Value),
                Messages = grp.Element("GroupMessages")
                             .Descendants("Message")
                             .Select(msg => new { 
                                 Id = msg.Element("MessageID").Value, 
                                 Message = msg.Element("GroupMessage").Value
                             }).ToList()
             };

但是,我强烈地强调 ,匿名类的所有这种用法只是要引起混乱。 如果你有一类GroupMessage ,然后使用这些。

请注意,您所遇到的问题是你忽略了XML结构和选择随机元素。 为了摆脱单一元素的值,你将需要精确地选择元素,并要求.Value 。 选择它的父,或它的父的父(像你一样)是不够的。



Answer 2:

尝试这个:

var groups = xDoc.Elements("Group")
            .Select(n => new
            {
                GroupName = n.Get("GroupName", string.Empty),
                GroupHeader = n.Get("GroupHeader", string.Empty),
                TimeCreated = n.Get("TimeAdded", DateTime.MinValue),
                Tags = n.Get("Tags", string.Empty),
                Messages = n.GetEnumerable("GroupMessages/Message", m => new
                {
                    Id = m.Get("MessageID", 0),
                    Message = m.Get("GroupMessage", string.Empty),
                    Group = m.Get("MessageGroup", string.Empty)
                }).ToArray()
            })
            .ToList();

我曾经从这里扩展方法: http://searisen.com/xmllib/extensions.wiki

获取将处理空情况下,像你的Tags节点不会在你的XML存在,以及空标签MessageGroup 。 您应该使用Elements()如果你想要的节点是你引用的节点的孩子,而不是由该名称的任何后代。

我复制你的XML转换为根节点进行测试。 它适用于这个XML:

<root>
  <Group>
    <TimeAdded>2012-04-27T10:23:50.7153613+01:00</TimeAdded>
    <GroupName>Group</GroupName>
    <GroupHeader>Header</GroupHeader>
    <GroupMessages>
      <Message>
        <MessageID>1</MessageID>
        <GroupMessage>Message</GroupMessage>
        <MessageGroup/>
      </Message>
    </GroupMessages>
  </Group>
  <Group>
    <TimeAdded>2012-04-27T10:23:50.7153613+01:00</TimeAdded>
    <GroupName>Group</GroupName>
    <GroupHeader>Header</GroupHeader>
    <GroupMessages>
      <Message>
        <MessageID>1</MessageID>
        <GroupMessage>Message</GroupMessage>
        <MessageGroup/>
      </Message>
    </GroupMessages>
  </Group>
</root>


文章来源: Select statement for xdoc query