| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Для новичков > Ошибка при работе с XML |
| Автор: Dom 22.7.2007, 11:34 | ||||
Есть xml-файл, следующего содержания
Написал функцию DefineISPNames для извлечения значений нод 'Name' в StringList. Работает отлично.
После создаю новую ноду <ISP> и ее детей и добавляю ее в начало списка. Затем снова вызываю DefineISPNames. Но в этот раз она считывает только одну первую ноду и на второй ноде (i =1) выдает ошибку в строке 20 Result.Add(Node.ChildNodes[i].ChildNodes['Name'].NodeValue) Ошибка вот какая - Project wsnake.exe raised exception class EOleException with message 'This operation can not be performed with a Node of type PCDATA'. Process stopped. Use Step or Run to continue. Что это за тип ноды PCDATA? Что-то ничего не могу найти про это ни в хелпах ни в инете. Кстати, если после добавления новой ноды <ISP> сохранить xml-файл, то в нем сохраняются все ноды, и добавленная и старые, и все на своих местах. Т.е. структура документа правильная. Надеюсь на вашу помощь. |
| Автор: ALeXandrK 26.7.2007, 18:01 | ||
Так может ты неправильно её создаешь (ноду). Прогони построчно через debuger и посмотри как изменяется твой документ после добавления в него новой ноды. Именно через debuger, а не сохраняя документ. Кстати, а если сохраненный документ с новой нодой, попытаться прогнать твоей функцией, тоже вылетит такая же ошибка на том же месте? PCDATA - анализируемые символьные данные или данные, которые обычно отображаются в браузере. P.s.: Раз уж приводишь код, так приводи весь, чтобы можно было самому погонять программу |
| Автор: Dom 26.7.2007, 18:55 | ||
Нет, если сохраненный документ снова открыть и считывать сожержимое нод этой функцией, то ошибки не возникает, и все ноды в т.ч. и новая отображаются правильно в создаваемом списке. Даже был такой топорный вариант - пересохранять файл, каждый раз после добавления ноды. Но рука до сих пор не поднялась на подобное. С debuger'ом попробую разобраться, раньше с ним не работал. Но спасибо за подсказку. Код сейчас приведу. У меня подозрение на несоместимость данных, т.е. я пытаюсь загнать в стринг содержимое ноды, а там как-будто не строка содержится. Может какое-то преобразование данных нужно... |
| Автор: ALeXandrK 26.7.2007, 19:31 | ||||
Самое простое, чтобы проверить, это перевести все в тип String и сохранять и читать его как String. Если это не поможет, значит ошибка не в типе. Нет... тут точно нужно debugerом гнать.
Тем более нельзя упускать такой шанс научиться им пользоваться - это все-равно рано или поздно придется делать. А сложного там ничего нет... так что дерзай P.s.: Если уж с нодами разобрался, то дебагер - это плёвое дело |
| Автор: Dom 26.7.2007, 19:53 | ||||||
Вот собственно все необходимые компоненты. Надеюсь комментарии помогут разобраться в деталях. Добавлено через 1 минуту и 4 секунды
Уже пробовал. Действительно ошибка не в типе. Добавлено через 7 минут и 10 секунд
Я не совсем уж новичок в программировании. Но вот с дебагером еще не сталкивался. Займусь. А с нодами разобраться несложно было. Тем более тут на форуме полно дельных советов есть и толковых кусочков кода. Это я решил для нашего хаба по-быстрому написать прогу для редактирования всех настроек, чтобы не руками лазить каждый раз. Однако процесс затянулся. |
| Автор: ALeXandrK 26.7.2007, 20:02 |
| А что за тип такой TAddNewISPForm? Я понимаю, что это форма, а в чём её задача? |
| Автор: Dom 26.7.2007, 20:09 | ||||
| Не совсем верный код запостил для процедуры AddNewISPNodeToXML Там надо добавить в начало строку
Более точная процедура бцдет выглядеть так.
Сорри. Надеюсь это не фатальная ошибка. И так ясно что присваиваются значения полей Edit. Добавлено через 1 минуту и 28 секунд AddNewISPForm это форма, на которой расположены Edit'ы и CheckBox'ы, значения которых и надо добавить в новую ноду |
| Автор: ALeXandrK 26.7.2007, 20:15 |
| Для полного счастья прикрепи свой xml файлик |
| Автор: Dom 26.7.2007, 20:22 | ||
Легко. Только не очень удивляйся всем полям в файле. Просто сейчас я сократил для простоты экспериментов процедуру добавления и отключил добавление всех дочерних нод, оставил только несколько. |
| Автор: ALeXandrK 26.7.2007, 20:31 | ||||
| Добавление проверил. Все верно... переходим на функцию DefineISPNames. Странно, но
При открытии это цикл выполняется дважды (у меня две ноды). Т.е. всё верно, но
Показывает, что в списке только один элемент. Ерунда какая-то |
| Автор: Dom 26.7.2007, 21:13 | ||
| Стоп. А куда ты последний цикл вставлял? Я выводил значения ISPNameList в ListBox вот таким образом
Добавлено через 2 минуты и 41 секунду На строки 6 и 7 не обращай внимания. Это я добавляю первым элементом строку с надписью All в один из листбоксов. |
| Автор: ALeXandrK 26.7.2007, 21:19 |
| Лохонусля... там все тоже ок |
| Автор: Dom 26.7.2007, 21:26 |
| Учусь пока обращатсья с дебаггером... Кстати у меня Делфи 7. Уже не знаю на что и думать. |
| Автор: ALeXandrK 26.7.2007, 21:38 | ||
Из-за этих строк и происходит билиберда, если они очень нужны, то ищи что-то в эту тему... видимо открытый файл нужно обновлять или что-то в этом роде, т.к. после вставки новых нод XML вообще пуст (это в памяти - можешь убедиться через дебагер |
| Автор: Dom 26.7.2007, 21:50 |
| Шаман! Благодарю за помощь! Что-нибудь уже дальше придумаем. Но учиться дебагингу все равно надо. Это как - купишь рыбу, будешь сыт день. Научишься ловить... К сожалению репутацию добавить не могу. Поэтому еще раз поблагодярю за то, что помог разобраться. |
| Автор: ALeXandrK 26.7.2007, 21:57 |
| Дебагинг - это неотъемлемая часть программирования. С его помощью можно экономить уйму времени Рад был помочь. Там видимо нужно после добавления обновлять, т.е. метод Refresh или Resync вызывать ... ну я думаю и без NodeIndent обойтись можно, если читать напрямую глазками XML документ не будешь... и лишнии байты сэкономишь |
| Автор: Lemon 12.11.2007, 05:56 |
| У меня тоже возникла подобная проблема. Вот как я ее решил. Если в опциях XML-документа включен параметр doNodeAutoIndent или в коде имеется строчка XMLDocData.Options := [doNodeAutoIndent], то строчка DataNode.ChildNodes[i].AddChild('Code').Text := '45'; даст ошибку "this operation can not be performed with a node of type PCDATA" i - это числовая переменная а если не использовать числовую переменную, а писать имя узла, то ошибки возникать не будет. Лично я не могу понять почему так происходит. А догадался чисто случайно. Рабочий пример: ParamNode := DataNode.AddChild('Object'); ParamNode.AddChild('Code').Text := '45'; ParamNode.AddChild('Name').Text := 'Test Name'; |