Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > [MVS2008] XML - хранение, добавление, удаление...


Автор: MuForum 11.3.2009, 19:05
Доброе время суток.
Работаю на "Microsoft Visual Studio 2008". Язык программирования C#.

# Задача: Необходимо записывать данные в структуру/объект, с дальнейшей возможностью обращения к определённому элементу, добавление элемента по определённому индексу, удаление определённого элемента по индексу.
- Для этой цели я решил выбрать '.XML'.

# Структуру данных:
Код

<Items>
  <Item a1="..." a2="..." ... an="..." />
  <Item a1="..." a2="..." ... an="..." />
  <Item a1="..." a2="..." ... an="..." />
  <Item a1="..." a2="..." ... an="..." />
  <Item a1="..." a2="..." ... an="..." />
  <Item a1="..." a2="..." ... an="..." />
  <Item a1="..." a2="..." ... an="..." />
  ...
</Items>

- Мне необходимо будет добавлять, удалять определённый индекс, например 3.
- говорю сразу, XML начал изучать только-только, так что ногами не пинать =)))


# Запись данных в .xml:
Код

XmlDocument xmldoc = new XmlDocument();
XmlElement xmlList = xmldoc.CreateElement("Items");
XmlElement sem = null;
xmldoc.AppendChild(xmlList);
int i, j;
for (i = 0; i < 10; i++)
{
    sem = xmldoc.CreateElement("Item");
    for(j = 0; j < 6; j++) sem.SetAttribute(j.ToString(), (j + 1).ToString());
    xmlList.AppendChild(sem);
}

- Чувствую, что криво, но не могу понять, как сделать нормально.
- А вот с добавление/удалением элемента по индексу вообще полная лажа...

# Удаление:
Код

XmlNodeList xmllist = g_xmldoc.SelectNodes("//Items/Item");
XmlNode tNode = xmllist[RowIndex].ParentNode;
XmlNode tParent = tNode.FirstChild;
tParent.RemoveChild(tNode);



P.S. -> В общем парни, прошу помочь, ибо сам пока не догоняю =(

Автор: Rififi 11.3.2009, 19:21
Говоришь только начал изучать.. а сам XPath уже юзаешь.. :gigi:

Я так понимаю, что xml нужен для возможности сохранять состояние обьекта между запусками программы. Тогда удобнее будет работать с классами C# и далее воспользоваться предоставляемой фреймворком возможностью сериализации
Код
[Serializable]
public class Item
{
    [XmlAttribute(AttributeName = "a1")]
    public int a1;
    // Другие поля
}

public List<Item> items;

using (StreamWriter wr = new StreamWriter("items.xml"))
{
    XmlSerializer sr = new XmlSerializer(items.GetType());
    sr.Serialize(wr, items);
}


и не нужно никакого гемора с add/remove childs

Автор: MuForum 11.3.2009, 19:24
#2, Rififi - Не совсем, мне данные как раз сохранять не надо.
- Мне нужно просто удобный объект, где я смогу хранить данные во время работы программы, и для удобной передачи указателя на объект между классами.

Автор: Rififi 11.3.2009, 19:34
MuForum, 
если данные нужны на время работы, то тогда выбор xml странен.
преимущества такого подхода неочевидны, а запарок много.

Автор: MuForum 11.3.2009, 19:46
Цитата(Rififi @ 11.3.2009,  19:34)
MuForum, 
если данные нужны на время работы, то тогда выбор xml странен.
преимущества такого подхода неочевидны, а запарок много.

Что тогда посоветуешь?
- Я до этого работал с коллекциями, а именно больше всего нравилась List<>.
Код

        public List<DataFileInfo> FileList = new List<DataFileInfo>();
        public class DataFileInfo
        {
            public bool Comment = false;
            // ----
            private string[] p = new string[28];
            public string this[int index]
            {
                get
                {
                    return (index >= 0 && index < 28) ? p[index] : string.Empty;
                }
                set
                {
                    if (index >= 0 && index < 28) p[index] = value;
                }
            }
        }

- Вот такого плана, но возникают проблемы при использовании, компилятор ругается, что нужно указывать на одну и туже структуру(с одного места). Собственно именно поэтому я и думал, может выбрать какуе-то системную.
+ Проблема ещё в том, что у меня при обработки разных данных, будет разное количество параметров.

Автор: Rififi 11.3.2009, 19:51
MuForum, 
компилятор ругается, что нужно указывать на одну и туже структуру(с одного места). 
этой фразы не понял...

Автор: MuForum 11.3.2009, 20:02
Я пишу программу для обработки/редактирования множества файлов, с различным внутренним строением/структурой.
- Для каждого файла пишу отдельный класс, в котором находиться нужная информация для обработки, функция чтения и обработки данных и т.д.
- Выше указанный мною пример использовать не удобно из-за того, что в моей программе одновременно может быть открыто несколько окон и соответственно обрабатываться несколько файлов.
- А для передачи указателя на эту структуру, я должен указать путь к ней.
- То есть, если в классах MyClass1 и MyClass2 располагаются идентичные структуры, но при вызове функции класса MyClass2 из MyClass1 указывая структуру из MyClass1, компилятор будет гураться...
Код

Error    2    Argument '1': cannot convert from 'System.Collections.Generic.List<DataEditor.FMain.DataFileInfo>' to 'System.Collections.Generic.List<DataEditor.TFindSystem.DataFileInfo>'

- Надеюсь теперь я доступно выразился.
- Именно по этой причине мне нужна какая-то такая структура, в которой я мог при необходимости наращивать массив значений, обращаться к определённому индексу, добавлять/удалять определённый элемент по индексу. (Ну и чтобы мог с легкость передавать указатель на эту структуру без такого гемороя)


# Добавлено: Можно конечно сделать некую эмитацию.
Код

        public List<DataFileInfo> FileList = new List<DataFileInfo>();
        public class DataFileInfo
        {
            public bool Comment = false;
            public List<string> Items = new List<string>();
        }

- Но опять же, это не совсем то, чтобы хотелось...

Автор: Magnetic 13.3.2009, 12:26
Цитата

Error    2    Argument '1': cannot convert from 'System.Collections.Generic.List<DataEditor.FMain.DataFileInfo>' to 'System.Collections.Generic.List<DataEditor.TFindSystem.DataFileInfo>'


Может подойдет использовать список List<object> или ArrayList и сохранять в него DataEditor.FMain.DataFileInfo и DataEditor.TFindSystem.DataFileInfo?

Автор: Rififi 13.3.2009, 13:02
MuForum, 
используй шаблоны проектирования http://ru.wikipedia.org/wiki/Composite и http://ru.wikipedia.org/wiki/Singleton

Автор: PashaPash 13.3.2009, 16:22
MuForum, 
То, что структуры в  FMain и в TFindSystem называются DataFileInfo, еще не значит что это одинаковые стурктуры. С точки зрения .net это два разных типа данных, как для тебя Лекарства.Свечи и Освещение.Свечи, с полями Длина и Толщина. Вынеси объявление в DataFileInfo из классов в отдельный файл - и оба класса придут к согласию.
Rififi, 0_o а без паттернов никак?

Автор: MuForum 14.3.2009, 12:18
Цитата(PashaPash @ 13.3.2009,  16:22)
MuForum, 
То, что структуры в  FMain и в TFindSystem называются DataFileInfo, еще не значит что это одинаковые стурктуры. С точки зрения .net это два разных типа данных, как для тебя Лекарства.Свечи и Освещение.Свечи, с полями Длина и Толщина. Вынеси объявление в DataFileInfo из классов в отдельный файл - и оба класса придут к согласию.
Rififi, 0_o а без паттернов никак?

Так и получилось.
Вынес в отдельное место свой класс< затем инициализируй. Думал сначала делать abstract, чтобы можно было наследовать и вносить изменения, а затем посмотрел и увидел, что мне то вносить изменения и не надо, только инициализировать.


P.S. -> Парни, не могли бы вы пожалуйста подсказать макулатуру с доступными(по возможности в сопровождение с кодом) объяснением классов/интерфейсов.
- С классами вроде более-немение дружу, а вот с интерфейсам полный аут =(

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)