【问题标题】:How do I select specific element name by using LINQ?如何使用 LINQ 选择特定元素名称?
【发布时间】:2021-09-17 15:31:13
【问题描述】:

如何选择每个带有<tweet> 元素的<Event> 并从下面的xml 文件中跳过<facebook-status-update> 并使用LINQ 显示其中的值?假设 xml 文件中有很多不同的事件,我只想选择 <Event><tweet> 元素及其内容

XML 文件内容:

<?xml version="1.0"?>
<Letter>
    <Body>
        <Event>
            <eventid>ID1</eventid>
            <tweet>
                <text>Tweet update</text>
                <location>
                    <lat>123</lat>
                    <long>456</long>
                </location>
                <datetimestamp>datetimestamp</datetimestamp>
            </tweet>
        </Event>
        <Event>
            <eventid>ID2</eventid>
            <facebook-status-update>
                <text>facebook status update</text>
                <location>
                    <lat>789</lat>
                    <long>101</long>
                </location>
                <datetimestamp>datetimestamp</datetimestamp>
            </facebook-status-update>
        </Event>
        <Event>
            <eventid>ID3</eventid>
            <tweet>
                <text>Tweet update</text>
                <location>
                    <lat>121</lat>
                    <long>314</long>
                </location>
                <datetimestamp>datetimestamp</datetimestamp>
            </tweet>
        </Event>
    </Body>
</Letter>

我正在使用 TwitterEvent 类来存储它自己的从 xml 文件中获取的事件值,并且我只能使用这个 C# 代码选择第一个 &lt;tweet&gt; 元素:

XDocument xmldoc = XDocument.Load(@"C:\Users\JACK\source\repos\LINQToObject\LINQToObject\Resources\xmlFile.xml");
var someEvents = (from _event in xmldoc.Descendants("Body").Elements("Event")                                 
                              select new TwitterEvent
                              {
                                  EventID = _event.Element("eventid").Value,
                                  TweetText = _event.Descendants("tweet").Elements("text").First().Value,
                                  Latitude = _event.Descendants("location").Elements("lat").First().Value,
                                  Longitude = _event.Descendants("location").Elements("long").First().Value,
                                  DateTimeStamp = _event.Descendants("tweet").Elements("datetimestamp").First().Value
                              });

预期输出:

ID1 Tweet update 123 456 datetimestamp
ID3 Tweet update 121 314 datetimestamp

【问题讨论】:

    标签: c# xml linq linq-to-xml


    【解决方案1】:

    你也可以试试这个。每个起始节点(如推文或位置)都将返回数组。所以,你需要从中选择。

            var events = XDocument.Load(@"D:\Github\EF\EF.Console\XMLFile1.xml").Descendants("Event");
            var eventResult = events.Where(x=>x.Element("tweet")!=null)
            .Select(_event => new Event
            {
                EventID = _event.Element("eventid").Value,
                TweetText = _event.Descendants("tweet").Select(x => x.Element("text").Value).FirstOrDefault(),
                DateTimeStamp = _event.Descendants("tweet").Select(x => x.Element("datetimestamp").Value).FirstOrDefault(),
                Lat = _event.Descendants("tweet").Select(x => x.Descendants("location").Select(y => y.Element("lat").Value).FirstOrDefault()).FirstOrDefault(),
                Long = _event.Descendants("tweet").Select(x => x.Descendants("location").Select(y => y.Element("long").Value).FirstOrDefault()).FirstOrDefault()
            }); 
    

    【讨论】:

    • 谢谢阿米特!这对我有用,我想支持你的答案,但不幸的是我没有足够的声誉。但是再次感谢您!
    • 欢迎并感谢您提出这么好的问题。对于upvote,我认为您可以再试一次。
    【解决方案2】:

    我不确定这是否正确,但你可以试试。

    我做了一个函数来检查像here这样的元素

    public static string TryGetElementValue(XElement parentEl, string elementName, string defaultValue = null)
    {
         var foundEl = parentEl.Element(elementName);
    
         if (foundEl != null)
         {
              return foundEl.Value;
         }
    
         return defaultValue;
    }
    

    然后我尝试添加where 来检查“tweet”元素:

    List<TwitterEvent> someEvents;
    someEvents = (from _event in xmldoc.Descendants("Body").Elements("Event")
                  where TryGetElementValue(_event, "tweet") != null
                  select new TwitterEvent()
                  {
                         EventID = _event.Element("eventid").Value,
                         TweetText = _event.Descendants("tweet").Elements("text").First().Value,
                         Latitude = _event.Descendants("location").Elements("lat").First().Value,
                         Longitude = _event.Descendants("location").Elements("long").First().Value,
                         DateTimeStamp = _event.Descendants("tweet").Elements("datetimestamp").First().Value
                  }).ToList<TwitterEvent>();
    

    【讨论】:

    • 为什么要使用整个方法? where 语句可以是:where _event.Element("tweet")!=null。在另一篇文章中,他们不得不一遍又一遍地这样做。在这里,检查只发生一次。
    • @dmedine 是的!你说得对!我没有考虑到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    相关资源
    最近更新 更多