Home Ask Login Register

Developers Planet

Your answer is one click away!

user5671675 February 2016

C# use Linq to pull data from xml

I have problem with building object holding XML data using Linq. For example, I have XML data in url http://api.eve-central.com/api/marketstat?typeid=34&usesystem=30000142 . In MarketStat class I want to hold type id value and in MarketValue class array I want to hold volume avg max min stddev median percentilevalues of buy sell all nodes. I have never used linq so far so please help me fix my problem in code below:

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").
                select new MarketStat
                    Name = (string) e.Element("type id"),
                    MarketValueses = (
                        from mv in e.Elements("buy")
                        select new MarketValue
                            Volume = (int) mv.Element("volume"),


Rahul Singh February 2016

The problem with your current code is that you want to fetch the id attribute of type element but you are trying to fetch it with type id which is wrong. Also you have the values of MarketValue in three nodes i.e. buy,sell & all but currently you are fetching details from just buy node.

This should give you the expected output:-

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")

Jon Skeet February 2016

You're looking for an element called "type id". That's not a valid name for an element in XML. You should just look for elements called type... that's the name of this element:

<type id="34">

If you want to filter by ID, you could then fetch the attribute id.

You're also trying to fetch the buy element directly from the marketstat element - it isn't there; it's within the type element. You need to pay more attention to the structure of the XML, basically.

My guess is that you should only expect a single buy element, too - which makes things simpler. I suspect you don't need an array within each element of your results...

bhmahler February 2016

You have a few things wrong with your xml parsing.

first of all you can't call type id as you do here

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

id is an attribute of the type element so you would have to do something like this

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

Another issue is in the section where you are trying to iterate the buy values. you have the following line

from mv in e.Elements("buy")

This will not work because e is the document root element. buy is a child of the type element so you would want something like this

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

Hope this helps and points you in the right direction

Here is a working example

list = (
    from e in XDocument.Load("http://api.eve-central.com/api/marketstat?typeid=34&usesystem=30000142").
        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)

** On a side note, when parsing that xml, the volume value was too large to fit into an int32 value so I changed it to a long

Post Status

Asked in February 2016
Viewed 2,351 times
Voted 9
Answered 3 times


Leave an answer

Quote of the day: live life