首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于xdoc查询的Select语句

用于xdoc查询的Select语句
EN

Stack Overflow用户
提问于 2012-04-27 04:42:52
回答 2查看 217关注 0票数 2

我正在尝试向我的xml语句中的消息添加子类别,有没有一种方法可以做到这一点,GroupMessages -> Message -> GroupMessage

代码语言:javascript
复制
        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同时包含MessageID和GroupMessage,并且在一个容器内的我的datagrid中列出了这两个内容。因此,我尝试了一下,但没有列出任何内容:

代码语言:javascript
复制
 Messages = n.Descendants("GroupMessages").Select(nd => nd.Element("GroupMessage").Value)

我的XML如下所示:

代码语言:javascript
复制
<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>

我也尝试过:

代码语言:javascript
复制
Messages = n.Descendants("GroupMessages").Select(nd => nd.Descendants("Message").Select(nde => nde.Element("GroupMessage").Value))

徒劳无功?

更新:

代码语言:javascript
复制
    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;
    }

不幸的是,这个方法在数据网格中的单元格中显示了"Collection“。如果我尝试ToArray,它将在单元格内显示一条数组消息。有没有一种方法可以真正显示GroupMessage?不确定如何设置数据网格的子元素?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-29 07:54:41

在最基本的级别上,您可以这样做以获得单个消息(第一个)

代码语言:javascript
复制
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和消息的消息列表。在这种情况下,请考虑以下内容:

代码语言:javascript
复制
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。选择它的父对象,或者它的父对象的父对象(如您所做的)是不够的。

票数 1
EN

Stack Overflow用户

发布于 2012-04-29 08:50:24

试试这个:

代码语言:javascript
复制
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

Get将处理空的情况,比如xml中不存在的Tags节点,以及空标记MessageGroup。如果需要的节点是所引用节点的子节点,而不是该名称的任何子节点,则应使用Elements()

我将您的xml复制到一个根节点来测试它。它在这个xml上工作:

代码语言:javascript
复制
<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>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10341145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档