如何使用linq解析下面的xml字符串到xml?

时间:2013-08-22 12:01:11

标签: c# xml linq-to-sql

XML:

<shift_details>
    <shift_time>10:00 to 10:30</shift_time>
    <count>0</count>
    <shift_time>10:30 to 11:00</shift_time>
    <count>0</count>
    <shift_time>11:00 to 11:30</shift_time>
    <count>0</count>
    <shift_time>11:30 to 12:00</shift_time>
    <count>0</count>
    <shift_time>12:00 to 12:30</shift_time>
    <count>0</count>
</shift_details>

代码:

var slots = from c in xmlResponse.Descendants("shift_details")
            select new TimeSlots
            {
                time = (string)c.Element("shift_time"),
                count = (string)c.Element("count"),
            };

上面的代码只返回一个插槽项作为输出。但我的xml包含太多记录。

如何读取上面xml中的所有记录?

2 个答案:

答案 0 :(得分:5)

那是因为Element仅返回具有给定名称的第一个元素。 您应该考虑更改XML结构以将不同的插槽彼此分开,例如:

<shift_details>
    <shift>
        <shift_time>10:00 to 10:30</shift_time>
        <count>0</count>
    </shift>
    (...)
</shift_details>

然后查询它:

var slots = from c in xmlResponse.Element("shift_details").Elements("shift")
            select new TimeSlots
            {
                time = (string)c.Element("shift_time"),
                count = (string)c.Element("count"),
            };

或者,如果您无法更改XML,您仍然可以查询它,但它会更棘手:

var doc = XDocument.Load("Input.txt");
var details = doc.Root;

var times = details.Elements("shift_time");
var counts = details.Elements("count");

var slots = times.Zip(counts, (t, c) => new { time = (string)t, count = (string)c }).ToList();

答案 1 :(得分:0)

另一方面,如果你不能改变XML的结构,你需要开始变得有创意(虽然我不推荐它)。在这种情况下,你可能会好起来(即使从长远来看可维护性较差)这样的东西,它需要一组元素并将它们分成每个包含独特元素的块:

public static class Extensions
{
    public static IEnumerable<IEnumerable<XElement>> Partition(this IEnumerable<XElement> elements)
    {
        var currentList = new List<XElement>();
        var tags = new HashSet<string>();

        foreach (var xElement in elements)
        {
            if (tags.Contains(xElement.Name.LocalName))
            {
                yield return currentList.ToArray();
                currentList.Clear();
                tags.Clear();
            }

            currentList.Add(xElement);
            tags.Add(xElement.Name.LocalName);
        }

        yield return currentList.ToArray();
    }
}

然后,您可以通过此操作在shift_details下运行子集合,并获得相当容易处理的组。应该从这里直截了当。