Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ноды с одинаковыми именами, но разными аттрибутами, Как перейти к следующему ноду? 
:(
    Опции темы
iddqd
Дата 9.3.2007, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 16.11.2005

Репутация: 0
Всего: 2



У меня есть функция для записи значения в нод.
Код

procedure TXmlClass.Write(Path: string; Key: string; Value: string);
var
  Node: IXMLNode;
  ts: TStringList;
  i: integer;
begin
  ts := TStringList.Create;
  ts.Delimiter := '\';
  ts.DelimitedText := Path;
  Node := XMLDoc.DocumentElement;
  if Node.ChildNodes.IndexOf(ts[0]) < 0 then
    Node := Node.AddChild(ts[0])
  else
    Node := Node.ChildNodes.FindNode(ts[0]);
  for I := 1 to ts.Count - 1 do
    begin
      if Node.ChildNodes.IndexOf(ts[i]) < 0 then
        Node := Node.AddChild(ts[i])
      else
        Node := Node.ChildNodes.FindNode(ts[i]);
    end;
  if Node.ChildNodes.IndexOf(Key) < 0 then
    Node := Node.AddChild(Key)
  else
    Node := Node.ChildNodes.FindNode(Key);
  Node.Text := Value;
  ts.Free;
end;


Появилась необходимость написать её так, чтоб можно было ходить по разным веткам, с разными аттрибутами.
Например:
Код

- <Internal>
- <DF id="D000">
  <EF id="D002">333232363538343836</EF> 
  </DF>
- <DF id="FF00">
  <EF id="F002">615B5F1F58503C55544F504554524F563C564F444B494E3C3C4956414E3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3332323635383438363255544F373831323131324D313031323133383C3C3C3C3C3C3C3C3C3C3C3C3C3C3032</EF> 
  </DF>
- <DF id="E000">
<EF id="E040">5E7BA37C10DDC479654BFE217C855A9924FF621BD7763696C3DEDCFA60EBFB6FA918120824200AFE3F60A89443E4EE9185FA91F0C727F38BE807B1C2C0449F04</EF> 
  <EF id="E041">308201633081FFA003020100020A0302030405060708090A301C06062A8503020203301206072A85030202230106072A850302021E013020311E301C06035504031315536174696E20434120636572746966696361746500301E170D3035303130313030303030305A170D3038303130313030303030305A3027312530230603550403131C536174696E20706572736F6E616C20636572746966696361746533003063301C06062A8503020213301206072A85030202230106072A850302021E010343020440E970AB6531E7DDB661D95A61DA2345D23C26F46A91EEF0F27A6B52F638F6BA1C716FCE1778DB0A4EE1F5954F0142F017E1C915FBF1F91C0F2A9746B66A2A9DF4301C06062A8503020203301206072A85030202230106072A850302021E01034100691BA75C6C71C68206FD8A72CBF4FA8D608151D5C9522DCA4A751BDF4CF97F15CFE9C0BB3BC77A59D4F928F83295303F8F01917DB4097FDA8A867017BF655EBD</EF> 
</DF>
  </Internal>


Обычно я писал вот так: 
Код

x.Write('Query\Passport\Chip\Internal\DF', 'EF', 'test');


Но сейчас написал новую функцию для записи с аттрибутами, которые указываются через символ ":" (двоеточие)
Функция выглядит так:
Код

procedure TXMLClass.WriteAttr(Path, Key, Value: string);
var
  Node: IXMLNode;
  tmp, ts, KV: TStringList;
  i, c: integer;
begin
  ts := TStringList.Create;
  tmp := TStringList.Create;
  KV := TStringList.Create;
  tmp.Delimiter := '\';
  tmp.DelimitedText := Path;
  for i := 0 to tmp.Count - 1 do
    begin
      if Pos(':', tmp[i]) > 0 then
        begin
          KV.Add(Copy(tmp[i], Pos(':', tmp[i]) + 1, Length(tmp[i])));
          ts.Add(Copy(tmp[i], 1, (Pos(':', tmp[i])) - 1));
        end
      else
        begin
          KV.Add('-');
          ts.Add(tmp[i]);
        end;
    end;
  Node := XMLDoc.DocumentElement;
  c := 0;
  repeat
    if Node.ChildNodes.IndexOf(ts[0]) < 0 then
      Node := Node.AddChild(ts[0])
    else
      Node := Node.ChildNodes.FindNode(ts[0]);
    if KV[0] = '-' then
      break
    else if Node.Attributes[KV.Names[0]] = KV.Values[KV.Names[0]] then
      break;
    Inc(c);
  until c > 10;
  c := 0;
  for I := 1 to ts.Count - 1 do
    begin
      repeat
        if Node.ChildNodes.IndexOf(ts[i]) < 0 then
          Node := Node.AddChild(ts[i])
        else
          Node := Node.ChildNodes.FindNode(ts[i]);
        if KV[i] = '-' then
          break
        else if Node.Attributes[KV.Names[i]] = KV.Values[KV.Names[i]] then
          break
        else
          Node.NextSibling;
        Inc(c);
      until c > 10;
    end;
  c := 0;
  KV.Clear;
  if Pos(':', Key) > 0 then
    begin
      KV.Add(Copy(Key, Pos(':', Key) + 1, Length(Key)));
    end
  else
    KV.Add('-');
  repeat
    if Node.ChildNodes.IndexOf(Key) < 0 then
      Node := Node.AddChild(Key)
    else
      Node := Node.ChildNodes.FindNode(Key);
    if KV[0] = ' ' then
      break
    else if Node.Attributes[KV.Names[0]] = KV.Values[KV.Names[0]] then
      break;
    Inc(c);
  until c > 10;
  Node.Text := Value;
  tmp.Free;
  ts.Free;
  KV.Free;
end;


Но функция постоянно теряет нужный нод. Она встаёт на нод <DF id="D000"> и никак не желает переходить на <DF id="FF00">.
Сейчас вызов функции выглядит так: 
Код

x.WriteAttr('Query\Passport\Chip\Internal\DF:id=E000', 'EF:id=E040', 'test');


Прошу помощи.

Собственно основная сложность вот в этом цикле:
Код

  for I := 1 to ts.Count - 1 do
    begin
      repeat
        if Node.ChildNodes.IndexOf(ts[i]) < 0 then
          Node := Node.AddChild(ts[i])
        else
          Node := Node.ChildNodes.FindNode(ts[i]);
        if KV[i] = '-' then
          break
        else if Node.Attributes[KV.Names[i]] = KV.Values[KV.Names[i]] then
          break
        else
          Node.NextSibling;
        Inc(c);
      until c > 10;
    end;


Это сообщение отредактировал(а) iddqd - 9.3.2007, 12:55


--------------------
PM MAIL   Вверх
iddqd
Дата 9.3.2007, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 16.11.2005

Репутация: 0
Всего: 2



По-моему удалось разобраться самостоятельно.
Код

procedure TXMLClass.WriteAttr(Path, Key, Value: string);
var
  Node, tmpNode: IXMLNode;
  tmp, ts, KV: TStringList;
  i, c: integer;
begin
  ts := TStringList.Create;
  tmp := TStringList.Create;
  KV := TStringList.Create;
  tmp.Delimiter := '\';
  tmp.DelimitedText := Path;
  for i := 0 to tmp.Count - 1 do
    begin
      if Pos(':', tmp[i]) > 0 then
        begin
          KV.Add(Copy(tmp[i], Pos(':', tmp[i]) + 1, Length(tmp[i])));
          ts.Add(Copy(tmp[i], 1, (Pos(':', tmp[i])) - 1));
        end
      else
        begin
          KV.Add('-');
          ts.Add(tmp[i]);
        end;
    end;

  Node := XMLDoc.DocumentElement;
  if Node.ChildNodes.IndexOf(ts[0]) < 0 then
    Node := Node.AddChild(ts[0])
  else
    Node := Node.ChildNodes.FindNode(ts[0]);

  tmpNode := Node;
  repeat
    if KV[0] = '-' then
      break;
    if (tmpNode.NodeName = ts[i]) and (tmpNode.Attributes[KV.Names[i]] = KV.Values[KV.Names[i]]) then
      break;
    tmpNode := tmpNode.NextSibling;
    if (tmpNode.NodeName = ts[i]) and (tmpNode.Attributes[KV.Names[i]] = KV.Values[KV.Names[i]]) then
      break;
  until false;

  Node := tmpNode;
  for I := 1 to ts.Count - 1 do
    begin
      if Node.ChildNodes.IndexOf(ts[i]) < 0 then
        Node := Node.AddChild(ts[i])
      else
        Node := Node.ChildNodes.FindNode(ts[i]);
      if KV[i] = '-' then
        continue;
      tmpNode := Node;
      repeat
        if (tmpNode.NodeName = ts[i]) and (tmpNode.Attributes[KV.Names[i]] = KV.Values[KV.Names[i]]) then
          break;
        tmpNode := tmpNode.NextSibling;
        if (tmpNode.NodeName = ts[i]) and (tmpNode.Attributes[KV.Names[i]] = KV.Values[KV.Names[i]]) then
          break;
      until false;
    end;

  Node := tmpNode;
  KV.Clear;

  if Pos(':', Key) > 0 then
    begin
      KV.Add(Copy(Key, Pos(':', Key) + 1, Length(Key)));
      Key := Copy(Key, 1, (Pos(':', Key)) - 1);
    end
  else
    KV.Add('-');

  if Node.ChildNodes.IndexOf(Key) < 0 then
    Node := Node.AddChild(Key)
  else
    Node := Node.ChildNodes.FindNode(Key);
  tmpNode := Node;
  repeat
    if KV[0] = '-' then
      break;
    if (tmpNode.NodeName = Key) and (tmpNode.Attributes[KV.Names[0]] = KV.Values[KV.Names[0]]) then
      break;
    tmpNode := tmpNode.NextSibling;
    if (tmpNode.NodeName = Key) and (tmpNode.Attributes[KV.Names[0]] = KV.Values[KV.Names[0]]) then
      break;
  until false;

  Node := tmpNode;

  Node.Text := Value;
  tmp.Free;
  ts.Free;
  KV.Free;
end;



--------------------
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0435 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.