如何使用 linq to xml 获取元素值并将其分配给 Double?
How to get element value and assign it to a Double using linq to xml?
我需要从下面的 xml 中获取所有 3 个 "avg" 值的值,然后将它们分配给一个双精度数组。使用 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>
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);
}
}
}
上面代码的问题是您只检索 avg
之一的值。使用 Descendants
你可以找到所有的 avg
然后得到值:
var result = xDoc.Descendants("avg").Select(e => (double)e);
如果你想确定它是 double
而不是失败和 InvalidCast 然后使用 double.TryParse
: 记住这有一个副作用使用了value
。如果你不想这样做,你可以在 where
中使用 TryParse
,然后在 select
中再次使用 Parse
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
属性:
double value = 0;
var result = (from element in xDoc.Descendants("avg")
where double.TryParse(element.Value, out value)
select new
{
Tag = element.Parent.Name.LocalName,
Value = value
}).ToList();
这些答案看起来非常冗长。如果您想要三个 avg
值,并且只有来自标签 <marketstat><type id="626">
的值,但是如果您想要避免更多的市场统计和类型,则必须深入挖掘。
double[] averages = xDoc.Descendants("avg")
.Select(xavg => (double)xavg)
.ToArray();
例如,
XElement type626 = xDoc.Descendants("type")
.First(x => (int)x.Attribute("id") == 626);
然后将前面的粘贴到这里,我们将 xDoc
替换为 type626
。
double[] averages = type626.Descendants("avg")
.Select(xavg => (double)xavg)
.ToArray();
在 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>
我需要从下面的 xml 中获取所有 3 个 "avg" 值的值,然后将它们分配给一个双精度数组。使用 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>
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);
}
}
}
上面代码的问题是您只检索 avg
之一的值。使用 Descendants
你可以找到所有的 avg
然后得到值:
var result = xDoc.Descendants("avg").Select(e => (double)e);
如果你想确定它是 double
而不是失败和 InvalidCast 然后使用 double.TryParse
: 记住这有一个副作用使用了value
。如果你不想这样做,你可以在 where
中使用 TryParse
,然后在 select
Parse
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
属性:
double value = 0;
var result = (from element in xDoc.Descendants("avg")
where double.TryParse(element.Value, out value)
select new
{
Tag = element.Parent.Name.LocalName,
Value = value
}).ToList();
这些答案看起来非常冗长。如果您想要三个 avg
值,并且只有来自标签 <marketstat><type id="626">
的值,但是如果您想要避免更多的市场统计和类型,则必须深入挖掘。
double[] averages = xDoc.Descendants("avg")
.Select(xavg => (double)xavg)
.ToArray();
例如,
XElement type626 = xDoc.Descendants("type")
.First(x => (int)x.Attribute("id") == 626);
然后将前面的粘贴到这里,我们将 xDoc
替换为 type626
。
double[] averages = type626.Descendants("avg")
.Select(xavg => (double)xavg)
.ToArray();
在 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>