|
Вопрос # 6 209/ вопрос решён / |
|
Доброго времени суток, уважаемые эксперты!
Мне необходимо создать документ XML, в котором будет несколько узлов,а внутри каждого узла ещё узлы... их может быть и 5 и 10....
с xml никогда не работал...
многие рекомендовали мне ECXMLParser его и использую. информации по нему очень мало я бы даже сказал вообще нет.....
ниже привожу код, который сделал.
Приложение: Переключить в обычный режим- a : TXMLItem;
- XML: TECXMLParser;
-
- XML := TECXMLParser.Create(Self);
- XML.Clear;
-
-
- a.Name :='name item';
- a.text:='my text1'+#13#10;
- a.params.values['par1']:='10';
- a.new.name:='name1';
-
-
-
-
- <?xml version="1.0" encoding="ISO8859-1" ?>
- <Test>
- <name item par1="10">
- my text<br/>
- <name1/>
- </name item>
- </Test>
-
-
-
-
-
-
-
- a.new.name:='name item2';
- a.new.text:='my text2'+#13#10;
- a.New.Params.Values['par2']:='20';
-
-
- <?xml version="1.0" encoding="ISO8859-1" ?>
- <Test>
- <name item1 par1="10">
- my text1<br/>
- <name item2/>
-
- my text2<br/>
- </>
- < par2="20"/>
- </name item1>
- </Test>
-
-
-
-
-
-
 |
Вопрос задал: yuta_86 (статус: Посетитель)
Вопрос отправлен: 25 июня 2012, 16:48
Состояние вопроса: решён, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 20; последнее сообщение — 26 июня 2012, 15:13; участников в обсуждении: 2.
|
min@y™ (статус: Доктор наук), 25 июня 2012, 17:55 [#1]:
TXMLItem.New() - это функция!
Ну почему создатели паскаля (в отличие от создателей Сишника) не сделали обязательными скобки при вызове функций без параметров?!!!11
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
min@y™ (статус: Доктор наук), 25 июня 2012, 18:05 [#2]:
Пример из моей проги:
procedure TEventOption.SaveToXML(AParentItem: TXMLItem);
var
Item, SubItem: TXMLItem; // <--- переменные, блин!
begin
// Сохранение в XML
inherited;
Item:= AParentItem.New(); // <--- функция, блин!
Item.Name:= FName;
XmlAddStringParam(Item, 'Caption', FCaption);
XmlAddIntegerParam(Item, 'OptionType', Integer(FOptionType));
XmlAddBoolParam(Item, 'Enabled', FEnabled);
XmlAddBoolParam(Item, 'ShowPicture', FShowPicture);
case FOptionType of
eotDaily: XmlAddTimeParam(Item, 'TriggerTime', FTriggerTime);
else XmlAddDateTimeParam(Item, 'TriggerTime', FTriggerTime);
end; // case
// дни недели срабатывания
if FOptionType = eotDaily
then XmlAddIntegerParam(Item, 'TriggerDaysOfWeek', DaysOfWeekToInt(FTriggerDaysOfWeek));
// звуковой файл
SubItem:= Item.New(); // <--- функция, блин!
SubItem.Name:= 'Sound';
XmlAddStringParam(SubItem, 'FileName', FSoundFile);
// картика или текстовое сообщение
SubItem:= Item.New(); // <--- функция, блин!
if FShowPicture
then begin
SubItem.Name:= 'Picture';
XmlAddStringParam(SubItem, 'FileName', FPictureFile);
end
else begin
SubItem.Name:= 'Message';
SubItem.Text:= FMessage;
end;
end;
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 25 июня 2012, 18:06 [#3]:
вопрос конечно интересный, а по существу есть что-то?
|
|
min@y™ (статус: Доктор наук), 25 июня 2012, 18:19 [#4]:
Цитата (yuta_86):
вопрос конечно интересный, а по существу есть что-то?
А чо, моих комментов и примера кода недостаточно? Ладно...
a.new.name:='name item2'; // <--- создал объект
a.new.text:='my text2'+#13#10; // <--- создал 2-й объект, ссылку на 1-й потерял
a.New.Params.Values['par2']:='20'; // <--- создал 3-й объект, потерял 2-й!
Молодец! Вижу, мой пример ты не смотрел. Продолжай в том же духе, ибо мне конкуренты ни к чему.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 25 июня 2012, 20:58 [#5]:
ой...когда писал коммент не было кода....извините
завтра на работе обязательно попробую сделать по аналогии. спасибо
|
|
yuta_86 (статус: Посетитель), 25 июня 2012, 21:02 [#6]:
код был дан раньше чем Ваш комментарий так что....
так ещё раз.... что значит потерял ссылку на объект.... зачем нужны ссылки ведь мы же создаём файл?потом его выводим в мемо и или сохраняем в файл.....видимо я что-то не понимаю.... можете пояснить?
|
|
min@y™ (статус: Доктор наук), 25 июня 2012, 21:03 [#7]:
Цитата (yuta_86):
завтра на работе обязательно попробую сделать по аналогии
Ну-ну...
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
25 июня 2012, 22:44: Вопрос перемещён из тематического раздела Delphi » Программирование баз данных (БД) в раздел Delphi » Алгоритмы, преобразования модератором Ерёмин А.А. Причина: А БД тут при чём?
|
yuta_86 (статус: Посетитель), 26 июня 2012, 09:48 [#8]:
итак посмотрел я ваш код попробовал.....
и чем же отличается ваш код
Item:= AParentItem.New(); // <--- функция, блин!
Item.Name:= FName;
XmlAddStringParam(Item, 'Caption', FCaption);
XmlAddIntegerParam(Item, 'OptionType', Integer(FOptionType));
XmlAddBoolParam(Item, 'Enabled', FEnabled);
XmlAddBoolParam(Item, 'ShowPicture', FShowPicture);
от моего
Items:=XML.Root.New;// <--- функция, блин! ))))
Items.Name:='name';
Items.params.values['Caption']:='your caption';
Items.params.values['OptionType']:='your OptionType';
Items.params.values['Enabled']:='your bool param';
Items.params.values['ShowPicture']:='your bool param';
я бы хотел получить структуру вида
<?xml version="1.0" encoding="cp1251"?>
<dbBuilder>
<dictionaries>
<measures>
<measure id="11" name="A" />
<measure id="12" name="В" />
<measure id="13" name="МВт" />
</measures>
<structure>
<users>
<user id="11" login="yuta" password="qwerty" name="Юрий" active="1" operator="1" dispatcher="1" admin="1" tcallowed="1" blockallowed="1" />
</users>
<usergroups>
<usergroup id="11" name="Супер_пользователи" />
<usergroup id="13" name="Диспетчеры" />
</usergroups>
<Districts>
<District ID="11" Name="РЭС" />
</Districts>
<IPAddresses>
<IPAddress ID="11" DAServerID="11" EthID="1" IPAddr="192.168.3.127" />
</IPAddresses>
</structure>
</dbBuilder>
про то почему создаётся кодировка ISO8859-1 ? как мне её поменять? на utf-8 например....
ни слова не сказали....
|
|
yuta_86 (статус: Посетитель), 26 июня 2012, 09:53 [#9]:
не понятно как сделать узлы <users> <Districts> и тд...
это ведь как разделы...в которых уже узлы с параметрами
<measure id="11" name="A" />
<user id="11" login="yuta" password="qwerty" name="Юрий" active="1" operator="1" dispatcher="1" admin="1" tcallowed="1" blockallowed="1" />
<District ID="11" Name="РЭС" /> и тд это всё ясно Item.New... и пошёл дальше...
|
|
min@y™ (статус: Доктор наук), 26 июня 2012, 10:32 [#10]:
В твоём XML нет закрывающего тега к тегу dictionaries. Я его убрал, получилось вот что:
<?xml version="1.0" encoding="cp1251"?>
<dbBuilder>
<measures>
<measure id="11" name="A" />
<measure id="12" name="В" />
<measure id="13" name="МВт" />
</measures>
<structure>
<users>
<user id="11" login="yuta" password="qwerty" name="Юрий" active="1" operator="1" dispatcher="1" admin="1"
tcallowed="1" blockallowed="1" />
</users>
<usergroups>
<usergroup id="11" name="Супер_пользователи" />
<usergroup id="13" name="Диспетчеры" />
</usergroups>
<Districts>
<District ID="11" Name="РЭС" />
</Districts>
<IPAddresses>
<IPAddress ID="11" DAServerID="11" EthID="1" IPAddr="192.168.3.127" />
</IPAddresses>
</structure>
</dbBuilder>
Вот пример кода для построения такой структуры:
var
Item, SubItem: TXMLItem;
begin
Parser.Root.Name:= 'dbBuilder';
Item:= Parser.Root.New(); // dbBuilder\measures
Item.Name:= 'measures';
SubItem:= Item.New(); // dbBuilder\measures\measure
SubItem.Name:= 'measure';
SubItem.Params.Add('id=11');
SubItem.Params.Add('name=А');
SubItem:= Item.New(); // dbBuilder\measures\measure
SubItem.Name:= 'measure';
SubItem.Params.Add('id=12');
SubItem.Params.Add('name=В');
SubItem:= Item.New(); // dbBuilder\measures\measure
SubItem.Name:= 'measure';
SubItem.Params.Add('id=13');
SubItem.Params.Add('name=МВт');
Item:= Parser.Root.New(); // dbBuilder\structure
Item.Name:= 'structure';
SubItem:= Item.New(); // dbBuilder\structure\users
SubItem.Name:= 'users';
with SubItem.New() do // dbBuilder\structure\users\user
begin
Name:= 'user';
Params.Add('id=11');
Params.Add('login=yuta');
Params.Add('password=qwerty');
// и так далее для остальных параметров
end;
SubItem:= Item.New(); // dbBuilder\structure\usergroups
SubItem.Name:= 'usergroups';
with SubItem.New() do // dbBuilder\structure\usergroups\usergroup
begin
Name:= 'usergroup';
Params.Add('id=11');
Params.Add('name=Супер_пользователи');
end;
with SubItem.New() do // dbBuilder\structure\usergroups\usergroup
begin
Name:= 'usergroup';
Params.Add('id=13');
Params.Add('name=Диспетчеры');
end;
// ... ну и так далее для остальных узлов и подузлов
end;
Цитата (yuta_86):
про то почему создаётся кодировка ISO8859-1 ? как мне её поменять? на utf-8 например.... ни слова не сказали....
Про кодировку - не знаю, меня устраивает та, что по умолчанию. Если хочешь, обработай исходники напильником или напиши письмо автору компонента.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 26 июня 2012, 10:52 [#11]:
ааа понятно это свойство NAME узла....
странно то что если SubItem.New()вызывать так то при запуске баг вылетает а если так SubItem.New то всё гуд.
смотрел форум и видел до этого что Вы min@y™: очень редко помогали людям в плане XML....a тут мне помогли...спасибо.вынужденен признать ВЫ ПРО. СПАСИБО
p.s. +1 к рейтингу
|
|
min@y™ (статус: Доктор наук), 26 июня 2012, 11:00 [#12]:
Цитата (yuta_86):
ааа понятно это свойство NAME узла....
Ну, дык, йопть!...
Цитата (yuta_86):
странно то что если SubItem.New()вызывать так то при запуске баг вылетает а если так SubItem.New то всё гуд.
Не верю! (© К. Станиславский)
Цитата (yuta_86):
смотрел форум и видел до этого что Вы min@y™: очень редко помогали людям в плане XML...
Да неужели? Плохо смотрел. Я здесь помогаю всем, если могу помочь и люди готовы эту помощь получить.
Цитата (yuta_86):
a тут мне помогли...спасибо.
Спасибо - это много. Пива достаточно! 
Цитата (yuta_86):
вынужденен признать ВЫ ПРО.
Не преувеличивай.
З.Ы. В качестве бонуса могу подарить пару самодельных вспомогательных модулей для работы с XML с помощью TECXMLParser.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 26 июня 2012, 11:02 [#13]:
Будете пить ПИВО потеряете статс ПРО....так что берегите себя.
|
|
min@y™ (статус: Доктор наук), 26 июня 2012, 11:06 [#14]:
Цитата (yuta_86):
Будете пить ПИВО потеряете статс ПРО....так что берегите себя.
Мне пох на статусы и прочую условную хню. А пиво я люблю. Мне 33 года, не надо меня учить жить: это неприлично.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 26 июня 2012, 11:10 [#15]:
ок...здоровье не вечно...я просто дал совет
|
|
yuta_86 (статус: Посетитель), 26 июня 2012, 13:41 [#16]:
min@y™: а каким образом после построения и вывода результата в мемо и сохранение в файл можно искать элемент?
например как мне найти
name=Супер_пользователи в <usergroup> а тот в <usergroups>
как происходит обход по документу?
|
|
min@y™ (статус: Доктор наук), 26 июня 2012, 14:38 [#17]:
Мемо выкинь, он не нужен. Хранение XML в памяти, а также сохранение в файл и загрузку из файла обеспечивает сам парсер.
Цитата (yuta_86):
например как мне найти name=Супер_пользователи в а тот в
Ну, как-то так:
var
UserGroupsItem, NeededItem: TXMLItem;
Index, ParamIndex: Integer;
begin
UserGroupsItem:= Parser.Root.NamedItem['structure'].NamedItem['usergroups'];
NeededItem:= nil;
for Index:= 0 to UserGroupsItem.Count - 1 do
begin
for ParamIndex:= 0 to UserGroupsItem[Index].Params.Count - 1 do
if (UserGroupsItem[Index].Params.Names[ParamIndex] = 'name') and
(UserGroupsItem[Index].Params.Values[ParamIndex] = 'Супер_пользователи')
then begin
NeededItem:= UserGroupsItem[Index]; // найдено
Break;
end;
if Assigned(NeededItem)
then Break;
end;
// далее - работа с NeededItem
end;
Однако, меня такой подход однозначно не устроил, очень муторный он. Поэтому я использую парсер только для загрузки и сохранения древовидной структуры в файл, а вот для хранения инфы в памяти использую отдельный класс, который сводит на нет потребность вообще в каком-либо поиске. Могу дать тебе пример такого класса.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 26 июня 2012, 14:51 [#18]:
ну понятное дело что
Parser: TECXMLParser;
Parser.SaveToFile('1.xml');
я так понимаю что когда мы пишем
Parser := TECXMLParser.Create(Self);
Item:= Parser.Root.New;
то у нас на создаётся xml документ а потом узел строится на основе документа? и ведь документ знает о структуре самого себя...ну как-то коряво объяснил...надеюсь вы поняли
так ли это?
а если я не знаю структуру документа но хочу найти какой-то элемент то как мне быть?
был бы рад получить пример )
|
|
min@y™ (статус: Доктор наук), 26 июня 2012, 15:08 [#19]:
Цитата (yuta_86):
а если я не знаю структуру документа но хочу найти какой-то элемент то как мне быть?
Тут надо просто написать рекурсивную функцию, подобную функции поиска файлов с заходом в подкаталоги.
Цитата (yuta_86):
был бы рад получить пример
Ну, создай новый вопрос. Будет время - напишу ответ. Укажи в вопросе входные данные, т.е. критерии поиска.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 26 июня 2012, 15:13 [#20]:
min@y™:
вот для хранения инфы в памяти использую отдельный класс, который сводит на нет потребность вообще в каком-либо поиске. Могу дать тебе пример такого класса.
я об этом говорил
по поводу темы сейчас создам
|
26 сентября 2012, 15:37: Статус вопроса изменён на решённый (изменил модератор DNK)
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|