IEnumerable将2个IEnumebles投射到一个类中

时间:2010-12-13 15:01:23

标签: .net xml linq-to-xml ienumerable

我有2个IEnumerables

IEnumerable<float> Distance
IEnumerable<XElement> Point

我想转换成

IEnumerable<Subsection> subsection

Class是

class Subsection
{
    public float Distance
    public XElement Point
}

但我不知道如何做到这一点,我已经尝试了一些铸造的变化,但没有一个有效,因为它们似乎不接受多个列表作为输入。

从xml文档中读取Distance和Point变量,其中这两个点的结构类似于:

<PLI>
    <Distance>5</Distance>
    <Point>23 22</Point>
    <Distance>7</Distance>
    <Point>21 72</Point>
    <Distance>9</Distance>
    <Point>13 32</Point>
</PLI>

我不确定如何将它们简单地作为分段类型读出来,但如果有人可以建议如何做到这一点,它将绕过我转换它的需要,因为我将不再拥有它们作为距离和点的IEnumerables但是作为结构。

请注意我无法修改XML

由于

编辑: XML还包含其他元素以及PLI标记中提到的元素,例如

<PLI>
    <OtherElement1>element1value</OtherElement1>
    <OtherElement2>element2value</OtherElement2>
    <Distance>5</Distance>
    <Point>23 22</Point>
    <Distance>7</Distance>
    <Point>21 72</Point>
    <Distance>9</Distance>
    <Point>13 32</Point>
</PLI>

2 个答案:

答案 0 :(得分:1)

这不是引用透明且完全不可取的,但是如果你对LINQ有所了解,那么对于这个特定问题,这是我现在最好的想法。这样您的订单就可以保证一致。

public class SubSection
{
    public float Distance;
    public XElement Point;

    public SubSection(XElement distance, XElement point)
    {
        Distance = float.Parse(distance.Value);
        Point = point;
    }
}
class Program
{
    static void Main(string[] args)
    {
        var c = XDocument.Parse(@"<PLI>
<Distance>5</Distance>
<Point>23 22</Point>
<Distance>7</Distance>
<Point>21 72</Point>
<Distance>9</Distance>
<Point>13 32</Point>
</PLI>");

        var sup = new List<SubSection>();
        c.Elements().Elements().Aggregate<XElement,XElement>(null, (a, d) =>
            {
                if (a == null)
                    return d;
                sup.Add(new SubSection(a, d));
                return null;
            });
        foreach (var entry in sup)
        {
            Console.WriteLine(entry.Distance);
        }

    }
}

答案 1 :(得分:1)

如果你的XML是平衡的(偶数个元素可以配对距离和点数),你可以在Enumerable.Zip method的帮助下用LINQ解决这个问题。

var query = xml.Elements("Distance")
               .Zip(xml.Elements("Point"),
                    (d, p) => new Subsection
                    {
                        Distance = float.Parse(d.Value),
                        Point = p
                    });

或者,您可以遍历元素并构建Subsection项。这可以通过以下方式完成,但它假定您的XML文档是平衡的并且是预期的格式。

var query = xml.Elements()
               .Where(e => e.Name.LocalName == "Distance"
                           || e.Name.LocalName == "Point");
var list = new List<Subsection>();
int count = 0;
Subsection s = null;
foreach (var element in query)
{
    if (count % 2 == 0)
        s = new Subsection { Distance = float.Parse(element.Value) };
    else
    {
        s.Point = element;
        list.Add(s);
    }

    count++;
}

请注意,在两个代码段中,xml变量都是XElement。对于XDocument添加Root属性,如xml.Root.Elements(...)