1

I want to grab one specific value within an XML document at a url, I have managed to get a list of all values, but I'm not sure how to choose the specific value. The XML document is as follows;

<evec_api version="2.0" method="marketstat_xml">
 <marketstat>
  <type id="37">
   <buy>
    <volume>291092912</volume>
    <avg>137.11</avg>
    <max>156.06</max>
    <min>53.46</min>
    <stddev>31.00</stddev>
    <median>140.28</median>
    <percentile>156.05</percentile>
   </buy>
   <sell>
    <volume>273042044</volume>
    <avg>177.43</avg>
    <max>339.00</max>
    <min>166.22</min>
    <stddev>30.83</stddev>
    <median>170.38</median>
    <percentile>166.26</percentile>
   </sell>
   <all>
    <volume>574134956</volume>
    <avg>154.64</avg>
    <max>339.00</max>
    <min>43.00</min>
    <stddev>42.21</stddev>
    <median>156.05</median>
    <percentile>69.98</percentile>
   </all>
  </type>
 </marketstat>
</evec_api>

The specific value I want is the min sell value, being 166.22. My code at current, which just retrieves all values in the document is

private void Form1_Load(object sender, EventArgs e)
{
    string xmlDocPath = "http://api.eve-central.com/api/marketstat?typeid=37&regionlimit=10000002&usesystem=30000142";
    XmlTextReader xmlReader = new XmlTextReader(xmlDocPath);
    while (xmlReader.Read())
    {
        if (xmlReader.NodeType == XmlNodeType.Text)
        {
            textBox1.AppendText(xmlReader.Value + "\n");
        }               
    }
}

I've tried a few different methods, like just throwing it all in a text box and taking the specific line, but that seems like a really silly solution. Most of the tutorials use console however that doesn't work for me. I feel it's probably a simple solution, but I'm yet to find one that works. Also, being fairly new to this, if there is anything terribly inefficient about this code, feel free to point it out.

  • 2
    Any reason you're using `XmlTextReader`? If you load the whole document into a LINQ to XML `XDocument`, your life will be considerably simpler. Also, you should separate in your mind "code from handling the XML" from "code to deal with the results" - just because some sample code uses the console doesn't mean it's useless to you; you should extract the XML-specific code from that and use it how you wish. – Jon Skeet Jun 04 '13 at 09:14
  • Try looking on ways to "parse xml" https://www.google.co.uk/search?q=how+to+parse+xml&oq=how+to+parse+xml&aqs=chrome.0.57j60l2j0l3.2107j0&sourceid=chrome&ie=UTF-8 or even here http://stackoverflow.com/questions/6442024/getting-specified-node-values-from-xml-document – dqm Jun 04 '13 at 09:15

2 Answers2

6

Try to use LINQ to XML, it's very straightforward. Example is given below:

var doc = XDocument.Parse(xml); //use XDocument.Load if you have path to a file

string minSell = doc.Descendants("sell")
                    .First()
                    .Element("min")
                    .Value;

Console.WriteLine(minSell); //prints 166.22
Ilya Ivanov
  • 23,148
  • 4
  • 64
  • 90
  • will FirstOrDefault() be better? – David Jun 04 '13 at 09:18
  • 1
    @David it really depends on a business logic. Should I also check for null on `Element("min")` ? These are open questions, which are better to negotiate with OP – Ilya Ivanov Jun 04 '13 at 09:19
  • Thanks, this seems like the way to go, I'd seen LINQ but not tried to use it as the solution I had seemed to work to an extent (I guess that's a bad attitude to have). To confirm, I would replace xml within the XDocument.Parse with the url of the XML document? In doing that it seems not to produce any result. I'll put some time into researching Linq in the meantime, I feel I can answer these questions myself with some time. – user2451011 Jun 04 '13 at 09:27
  • Linq To XML is a generic microsoft only technology. XPath allows you to do this in a much more generic (runtime changable) manner. Additionally microsoft's implementation of XPath and XML in general has been heavily optimised. – Uatec Jun 04 '13 at 09:27
  • Regarding my previous comment/question, nevermind I made a silly. I had to use XDocument.Load, as you said. – user2451011 Jun 04 '13 at 09:33
2

If you wrap that XmlTextReader into a XmlDocument you can then execute an XPath query on it to retrieve the specific node you're interested in:

var doc = new XmlDocument(xmlReader);
doc.Load();
var xpath = "/marketstat/type [@id='37']/sell/min";
var myNode = doc.SelectSingleNode(xpath);
slugster
  • 49,403
  • 14
  • 95
  • 145