|
Вопрос # 6 211/ вопрос закрыт / |
|
Здравствуйте, уважаемые эксперты!
Каким образом осуществляется поиск по xml документу?
использую ECXMLParser.
заранее не знаю структуру всего документа
вот например документ в котором мне надо найти пароли всех пользователей ну или имена всех групп пользователей....
Приложение: Переключить в обычный режим- <?xml version="1.0" encoding="cp1251"?>
- <dbBuilder>
- <measures>
- <measure id="11" name="A" />
-
-
- </measures>
-
- <structure>
- <users>
-
- tcallowed="1" blockallowed="1" />
- </users>
-
- <usergroups>
-
-
- </usergroups>
-
- <Districts>
-
- </Districts>
-
- <IPAddresses>
- <IPAddress ID="11" DAServerID="11" EthID="1"
IPAddr="192.168.3.127" />
- </IPAddresses>
- </structure>
- </dbBuilder>
 |
Вопрос задал: yuta_86 (статус: Посетитель)
Вопрос отправлен: 26 июня 2012, 15:24
Состояние вопроса: закрыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: min@y™
// Процедура рекурсивного поиска всех XML-подузлов внутри узла AParentItem,
// имеющих имя AName. Найденные подузлы помещаются в список AResults,
// который перед вызовом процедуры надо очистить.
procedure FindItems(AParentItem: TXMLItem; const AName: string; AResults: TList);
var
Index: Integer;
begin
for Index:= 0 to AParentItem.Count - 1 do
begin
if AParentItem[Index].Name = AName // проверка имени
then AResults.Add(AParentItem[Index]); // добавление в список
if AParentItem[Index].Count <> 0 // если есть подузлы, то...
then FindItems(AParentItem[Index], AName, AResults); // поиск в подузлах (рекурсия)
end;
end;
// Пример вызова:
var
Items: TList;
Index: Integer;
Item: TXMLItem;
begin
Items:= TList.Create();
try
FindItems(Parser.Root, 'user', Items); // поиск
for Index:= 0 to Items.Count - 1 do
begin
Item:= TXMLItem(Items[Index]);
// <--- тут - требуемая работа с найденными подузлами
end;
finally
Items.Free();
end;
end;
// Ахтунг! Код не отлаживал, писал на заборе! :)
По аналогии с этой процедурой можно сделать поиск по именам и/или значениям параметров узлов.
 |
Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 26 июня 2012, 15:56
|
Мини-форум вопроса
Всего сообщений: 11; последнее сообщение — 27 июня 2012, 13:15; участников в обсуждении: 2.
26 июня 2012, 16:01: Вопрос перемещён из тематического раздела Delphi » Прочее в раздел Delphi » Работа с компонентами и библиотеками модератором DNK
|
yuta_86 (статус: Посетитель), 26 июня 2012, 16:37 [#1]:
а вытаскивать значение параметра так?
Item.Params[0] ? если ищем user то будет значение id=11 а как получить значение 11
можно ли как-то сделать типа
edit1.text:=Item.params['id'].value ))
|
|
min@y™ (статус: Доктор наук), 26 июня 2012, 16:51 [#2]:
Цитата (yuta_86):
а вытаскивать значение параметра так?
Вот тебе мой самодельный модуль. Там всё для этого есть.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 26 июня 2012, 17:04 [#3]:
модуль очень полезен..... меня удивляет как вы до этого дошли ведь описания TECXMLParser вообще нет ведь....
|
|
yuta_86 (статус: Посетитель), 26 июня 2012, 17:04 [#4]:
СПАСИБО
|
|
min@y™ (статус: Доктор наук), 26 июня 2012, 21:00 [#5]:
Цитата (yuta_86):
меня удивляет как вы до этого дошли ведь описания TECXMLParser вообще нет ведь.
А нахрена мне описание, когда исходники и демо-примеры есть? К тому же имена свойств и методов несут хорошую смысловую нагрузку.
Цитата (yuta_86):
СПАСИБО
Пива достаточно.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 27 июня 2012, 10:50 [#6]:
вот я нашёл элемент это всё гуд. а как теперь заменить в нём значение параметра?
например
поменять Диспетчеры на что-то другое?
|
|
min@y™ (статус: Доктор наук), 27 июня 2012, 11:16 [#7]:
Допустим, что ты нашёл элемент и записал его адрес в переменную Item: TXMLItem.
Параметры хранятся в свойстве TXMLItem.Params: TStrings в формате имя_параметра="значение". Для изменения значения воспользуйся свойством TStrings.Values[const Name: string]: string;
Цитата (yuta_86):
например поменять Диспетчеры на что-то другое?
Для твоего примера:
Item.Params.Values['name']:= 'Уборщицы';
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 27 июня 2012, 11:27 [#8]:
да это понятно но дело в том что если я хочу сохранить результаты в тот же файл.
|
|
min@y™ (статус: Доктор наук), 27 июня 2012, 11:48 [#9]:
Цитата (yuta_86):
да это понятно но дело в том что если я хочу сохранить результаты в тот же файл.
И что? Загрузил файл, изменил что нужно, сохранил файл. Какие тут могут быть проблемы?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
yuta_86 (статус: Посетитель), 27 июня 2012, 12:05 [#10]:
да верно.... правильно сделал так
Parser := TECXMLParser.Create(Self);
Parser.Clear;
Parser.LoadFromFile('1.xml');
Items:= TList.Create();
try
Form1.FindItems(Parser.Root, 'usergroup', Items); // поиск
Item:=TXMLItem(Items[0]);
Item.Params.Values['name']:= 'Уборщицы';
Item.Params.Values['id']:= '123';
finally
Items.Free();
end;
Parser.SaveToFile('1.xml');
в данном случае для первой записи. так должно быть? замечания или предложения есть?
|
|
min@y™ (статус: Доктор наук), 27 июня 2012, 13:15 [#11]:
Цитата (yuta_86):
замечания или предложения есть?
Есть:
Parser := TECXMLParser.Create(Self); // заменить Self на nil
Parser.Clear; // убрать эту строку
Parser.LoadFromFile('1.xml');
Items:= TList.Create();
try
Form1.FindItems(Parser.Root, 'usergroup', Items); // поиск
Item:=TXMLItem(Items[0]); // здесь получишь Access Violation, если ничего не найдено
Item.Params.Values['name']:= 'Уборщицы';
Item.Params.Values['id']:= '123';
finally
Items.Free();
end;
Parser.SaveToFile('1.xml');
// добавить убиение парсера, а то утечка памяти будет.
Я бы сделал примерно вот в таком духе:
function TForm1.ChangeParam: Boolean;
var
Parser: TECXMLParser;
begin
Parser:= TECXMLParser.Create(nil);
Items:= TList.Create();
Result:= True;
try
try
Parser.LoadFromFile('1.xml');
except
Result:= False;
end;
if not Result
then Exit;
FindItems(Parser.Root, 'usergroup', Items); // поиск
if Items.Count <> 0
then with TXMLItem(Items[0]).Params do
begin
Values['name']:= 'Уборщицы';
Values['id']:= '123';
end;
try
Parser.SaveToFile('1.xml');
except
Result:= False;
end;
finally
Items.Free();
Parser.Free();
end;
end;
Цитата (yuta_86):
в данном случае для первой записи.
А что делать, если найдено несколько записей - решай сам.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
30 июля 2012, 12:30: Вопрос закрыт (решение принял DNK): на первый взгляд вопрос исчерпан
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|