如何获取元素值并使用linq to xml将其分配给Double?

时间:2016-10-20 16:44:27

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

我需要从以下xml中获取所有3个“avg”值的值,然后将它们分配给double数组。使用linq到xml。我是linq to xml的新手,所以我不太清楚如何解决这个问题。

这是我目前的代码

var q = from e in xDoc.Descendants("sell")
        select new
        {
            result = e.Element("avg").Value
        };

XML:

<?xml version='1.0' encoding='utf-8'?>
<evec_api version="2.0" method="marketstat_xml">
    <marketstat>
        <type id="626">
            <buy>
                <volume>11</volume>
                <avg>9345454.55</avg>
                <max>11500000.00</max>
                <min>7500000.00</min>
                <stddev>1862495.34</stddev>
                <median>7600000.00</median>
                <percentile>11500000.00</percentile>
            </buy>
            <sell>
                <volume>23</volume>
                <avg>18749987.25</avg>
                <max>18749987.25</max>
                <min>18749987.25</min>
                <stddev>0.00</stddev>
                <median>18749987.25</median>
                <percentile>18749987.25</percentile>
            </sell>
            <all>
                <volume>34</volume>
                <avg>15707344.32</avg>
                <max>18749987.25</max>
                <min>7500000.00</min>
                <stddev>4573474.77</stddev>
                <median>18749987.25</median>
                <percentile>7500000.00</percentile>
            </all>
        </type>
    </marketstat>
</evec_api>

4 个答案:

答案 0 :(得分:1)

These answers seem awfully verbose. If you want the three avg values, and there are only those from the tags <marketstat><type id="626"> but if there are more marketstat's and type that you want to avoid, you'll have to dig deeper.

double[] averages = xDoc.Descendants("avg")
                        .Select(xavg => (double)xavg)
                        .ToArray();

For instance,

XElement type626 = xDoc.Descendants("type")
                       .First(x => (int)x.Attribute("id") == 626);

Then paste the earlier into this, we replace xDoc with type626.

double[] averages = type626.Descendants("avg")
                        .Select(xavg => (double)xavg)
                        .ToArray();

答案 1 :(得分:0)

using System;
using System.Linq;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            var xml = @"<?xml version='1.0' encoding='utf-8'?>
<evec_api version=""2.0"" method=""marketstat_xml"">
    <marketstat>
        <type id=""626"">
            <buy>
                <volume>11</volume>
                <avg>9345454.55</avg>
                <max>11500000.00</max>
                <min>7500000.00</min>
                <stddev>1862495.34</stddev>
                <median>7600000.00</median>
                <percentile>11500000.00</percentile>
            </buy>
            <sell>
                <volume>23</volume>
                <avg>18749987.25</avg>
                <max>18749987.25</max>
                <min>18749987.25</min>
                <stddev>0.00</stddev>
                <median>18749987.25</median>
                <percentile>18749987.25</percentile>
            </sell>
            <all>
                <volume>34</volume>
                <avg>15707344.32</avg>
                <max>18749987.25</max>
                <min>7500000.00</min>
                <stddev>4573474.77</stddev>
                <median>18749987.25</median>
                <percentile>7500000.00</percentile>
            </all>
        </type>
    </marketstat>
</evec_api>";

            var xdoc = XDocument.Parse(xml);
            var typeElement = xdoc.Element("evec_api").Element("marketstat").Element("type");
            var avgElements = typeElement.Elements().Select(e => e.Element("avg"));

            foreach (var avgElement in avgElements)
                Console.WriteLine(avgElement.Value);
        }
    }
}

答案 2 :(得分:0)

在VB .Net中我会做

    Dim avgs() As Double = xe...<avg>.Select(Function(a) CDbl(a.Value)).ToArray

在C#中看起来像这样(根据我使用的转换器)

double[] avgs = xe.Select(a => Convert.ToDouble(a.Value)).ToArray;

使用

进行测试
    Dim xe As XElement
    'to load from a file
    '  xe = XElement.Load("Your Path Here")

    ' for testing
    xe = <evec_api version="2.0" method="marketstat_xml">
             <marketstat>
                 <type id="626">
                     <buy>
                         <volume>11</volume>
                         <avg>9345454.55</avg>
                         <max>11500000.00</max>
                         <min>7500000.00</min>
                         <stddev>1862495.34</stddev>
                         <median>7600000.00</median>
                         <percentile>11500000.00</percentile>
                     </buy>
                     <sell>
                         <volume>23</volume>
                         <avg>18749987.25</avg>
                         <max>18749987.25</max>
                         <min>18749987.25</min>
                         <stddev>0.00</stddev>
                         <median>18749987.25</median>
                         <percentile>18749987.25</percentile>
                     </sell>
                     <all>
                         <volume>34</volume>
                         <avg>15707344.32</avg>
                         <max>18749987.25</max>
                         <min>7500000.00</min>
                         <stddev>4573474.77</stddev>
                         <median>18749987.25</median>
                         <percentile>7500000.00</percentile>
                     </all>
                 </type>
             </marketstat>
         </evec_api>

答案 3 :(得分:-1)

上面代码的问题在于您只检索avg之一的值。使用Descendants,您可以找到所有avg,然后获取值:

var result = xDoc.Descendants("avg").Select(e => (double)e);

如果你想确定它是double并且没有失败并且InvalidCast那么请使用double.TryParse请记住,这通过使用{会产生副作用{1}}。如果您不想这样做,可以value使用TryParsewhere

再使用Parse
select

如果您希望结果在数字和来自哪里之间有一些暗杀,您可以使用double value = 0; var result = (from element in xDoc.Descendants("avg") where double.TryParse(element.Value, out value) select value).ToList(); // result: 9345454.55, 18749987.25, 15707344.32 属性:

.Parent

enter image description here