C # новичок: чтение повторяющегося XML в память

2

Я новичок в С#. Я создаю приложение, которое сохраняет XML файл со списком элементов. Структура моего XML файла выглядит следующим образом:

<Elements>
    <Element>
        <Name>Value</Name>
        <Type>Value</Type>
        <Color>Value</Color>
    </Element>
    <Element>
        <Name>Value</Name>
        <Type>Value</Type>
        <Color>Value</Color>
    </Element>
    <Element>
        <Name>Value</Name>
        <Type>Value</Type>
        <Color>Value</Color>
    </Element>
</Elements>

У меня есть < 100 из этих элементов, и это единственный список (поэтому я рассматриваю решение БД, которое может быть переполнено, даже SQLite). Когда мое приложение загружается, я хочу прочитать этот список элементов в памяти. В настоящее время, немного просмотрев веб-сайт, я использую XmlTextReader.

Однако, возможно, я использую его не так, я читаю теги данных по тегам и, следовательно, ожидаю, что теги будут в определенном порядке (иначе код будет грязным). То, что я хотел бы сделать, это прочитать полные структуры "Элемент" и извлечь теги из них по имени. Я уверен, что это возможно, но как?

Чтобы пояснить, основное отличие заключается в том, что сегодня я использую XmlTextReader, он не допускает сценариев, таких как неправильный порядок тегов (например, Тип приходит до имени в определенном элементе).

Какая наилучшая практика для загрузки таких структур в память на С#?

Теги:

5 ответов

5
Лучший ответ

Любая конкретная причина, по которой вы не используете XmlDocument?

XmlDocument myDoc = new XmlDocument()
myDoc.Load(fileName);

foreach(XmlElement elem in myDoc.SelectNodes("Elements/Element"))
{
    XmlNode nodeName = elem.SelectSingleNode("Name/text()");
    XmlNode nodeType = elem.SelectSingleNode("Type/text()");
    XmlNode nodeColor = elem.SelectSingleNode("Color/text()");

    string name = nodeName!=null ? nodeName.Value : String.Empty;
    string type = nodeType!=null ? nodeType.Value : String.Empty;
    string color = nodeColor!=null ? nodeColor.Value : String.Empty;

    // Here you use the values for something...
}
  • 0
    Возможно, мой XPath плох, но не получит ли @Name атрибут Name?
  • 0
    @Jon - Вы правы - это решение не будет работать так, как написано.
Показать ещё 5 комментариев
10

Это очень легко сделать в LINQ to XML. Вы используете .NET 3.5? Здесь образец:

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

class Test
{
    [STAThread]
    static void Main()
    {
        XDocument document = XDocument.Load("test.xml");

        var items = document.Root
                            .Elements("Element")
                            .Select(element => new {
                                Name = (string)element.Element("Name"),
                                Type = (string)element.Element("Type"),
                                Color = (string)element.Element("Color")})
                            .ToList();

        foreach (var x in items)
        {
            Console.WriteLine(x);
        }
    }
}

Возможно, вы захотите создать свою собственную структуру данных для хранения каждого элемента, но вам просто нужно изменить вызов "Выбрать", чтобы использовать это.

  • 0
    +1 Это самое простое решение - красиво сделано.
  • 1
    Будем все благодарны за LINQ, я думаю, что это излишне для моих простых требований. Все, что мне нужно, это загрузить информацию один раз в память ...
Показать ещё 3 комментария
1

Звучит как XDocument, и XElement может быть лучше подходит для этой задачи. У них может не быть абсолютной скорости XmlTextReader, но для ваших случаев они звучат так, как будто они были бы подходящими, и это упростило бы работу с фиксированными структурами. Разбор элементов будет работать следующим образом:

XDocument xml;

foreach (XElement el in xml.Element("Elements").Elements("Element")) {
     var name = el.Element("Name").Value;
     // etc.
}

Вы даже можете немного полюбить Linq:

XDocument xml;

var collection = from el in xml.Element("Elements").Elements("Element")
                 select new { Name = el.Element("Name").Value,
                              Color = el.Element("Color").Value,
                              Type = el.Element("Type").Value
                            };


foreach (var item in collection) {
    // here you can use item.Color, item.Name, etc..
}
1

Вы можете использовать класс XmlSerializer (http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx)

    public class Element
{
    public string Name { get; set; }
    public string Type { get; set; }
    public string Color { get; set; }
}

class Program
{

    static void Main(string[] args)
    {
        string xml =
            @"<Elements>
<Element>
    <Name>Value</Name>
    <Type>Value</Type>
    <Color>Value</Color>
</Element>(...)</Elements>";

XmlSerializer serializer = new XmlSerializer(typeof(Element[]), new XmlRootAttribute("Elements"));
        Element[] result = (Element[])serializer.Deserialize(new StringReader(xml));}
  • 0
    Да, но ему лучше не будет. В нем осталось мало будущего.
0

Вы должны проверить Linq2Xml, http://www.hookedonlinq.com/LINQtoXML5MinuteOverview.ashx

Ещё вопросы

Сообщество Overcoder
Наверх
Меню