C#使用Linq从xml中提取数据

时间:2016-02-08 16:13:48

标签: c# arrays linq

我在使用Linq构建持有XML数据的对象时遇到问题。例如,我在url http://api.eve-central.com/api/marketstat?typeid=34&usesystem=30000142中有XML数据。在MarketStat课程中,我希望保留type id值,在MarketValue类数组中,我想要暂停volume avg max min stddev median percentilebuy sell all个节点的值。到目前为止我从未使用过linq,所以请帮我解决下面代码中的问题:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    internal class MarketValue
    {
        public int Volume { get; set; }
        public double Avg { get; set; }
        public double Max { get; set; }
        public double Min { get; set; }
        public double Stddev { get; set; }
        public double Median { get; set; }
        public double Percentile { get; set; }
    }
    internal class MarketStat
    {
        public string Name { get; set; }
        public MarketValue[] MarketValueses { get; set; }
    }
    internal class Program
    {
        private static List<MarketStat> list;
        internal static void Main(string[] args)
        {
            list = (
                from e in XDocument.Load("http://api.eve-central.com/api/marketstat?typeid=34&usesystem=30000142").
                    Root.Elements("marketstat")
                select new MarketStat
                {
                    Name = (string) e.Element("type id"),
                    MarketValueses = (
                        from mv in e.Elements("buy")
                        select new MarketValue
                        {
                            Volume = (int) mv.Element("volume"),
                            Avg = (double) mv.Element("avg"),
                            Max = (double)mv.Element("max"),
                            Min = (double)mv.Element("min"),
                            Stddev = (double)mv.Element("stddev"),
                            Median = (double)mv.Element("median"),
                            Percentile = (double)mv.Element("percentile")
                        }).ToArray()
               }).ToList();
         }
    }
}

3 个答案:

答案 0 :(得分:3)

您当前代码的问题在于您要获取id元素的type属性,但是您尝试使用type id来获取它,这是错误的。此外,您在三个节点中的值为MarketValue,即 buy,sell&amp;所有但目前您只是从购买节点获取详细信息。

这应该给你预期的输出: -

XDocument xdoc = XDocument.Load("http://api.eve-central.c...
var result = xdoc.Root.Elements("type")
                 .Select(ms => new MarketStat
                    {
                        Name = (string)ms.Attribute("id"),
                        MarketValueses = ms.Elements()
                                      .Select(mv => new MarketValue
                                         {
                                             Volume = (long)mv.Element("volume"),
                                             Avg = (double)mv.Element("avg"),
                                             Max = (double)mv.Element("max"),
                                             Min = (double)mv.Element("min"),
                                             Stddev = (double)mv.Element("stddev"),
                                             Median = (double)mv.Element("median"),
                                             Percentile = (double)mv.Element("percentile")
                                         }).ToArray()
                             }).ToList();

答案 1 :(得分:1)

您正在寻找名为“type id”的元素。这不是XML中元素的有效名称。您应该只查找名为type的元素...这是该元素的名称:

<type id="34">

如果您想按ID过滤,则可以获取属性 id

您还试图直接从buy元素中获取marketstat元素 - 它不存在;它在type元素内。基本上,你需要更多地关注XML的结构。

我的猜测是,您应该只期望一个buy元素 - 这会使事情变得更简单。我怀疑你在结果的每个元素中都不需要数组......

答案 2 :(得分:0)

你的xml解析有些问题。

首先,你不能像在这里一样调用类型ID

Name = (string) e.Element("type id")

id是type元素的一个属性,所以你必须做这样的事情

Name = e.Element("type").Attributes("id").Value

另一个问题是您尝试迭代购买价值的部分。 你有以下一行

from mv in e.Elements("buy")

这不起作用,因为e是文档根元素。 buy是type元素的子元素,所以你会想要这样的东西

from mv in e.Elements("type").Descendants("buy")

希望这会有所帮助并指出正确的方向

这是一个工作示例

list = (
    from e in XDocument.Load("http://api.eve-central.com/api/marketstat?typeid=34&usesystem=30000142").
        Root.Elements("marketstat")
        let type = e.Element("type")
    select new MarketStat
    {
        Name = type.Attribute("id").Value,
        MarketValueses = (
            from mv in type.Descendants("buy")
            select new MarketValue
            {
                Volume = long.Parse(mv.Element("volume").Value),
                Avg = double.Parse(mv.Element("avg").Value),
                Max = double.Parse(mv.Element("max").Value),
                Min = double.Parse(mv.Element("min").Value),
                Stddev = double.Parse(mv.Element("stddev").Value),
                Median = double.Parse(mv.Element("median").Value),
                Percentile = double.Parse(mv.Element("percentile").Value)
            }).ToArray()
    }).ToList();

**在旁注中,解析该xml时,音量值太大而无法插入int32值,因此我将其更改为长