Вопрос про XML (FindNode)[Решено](Баян)

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Вопрос про XML (FindNode)[Решено](Баян)

Сообщение Maxizar »

Работаю с XML файлом, сначала разработал такую вот процедуру:

Код: Выделить всё

procedure TOODocument.SetMetaData(const AValue: TMYData);
var RootNode,Node: TDOMNode;
begin


 RootNode:=FMeta.DocumentElement.FindNode('office:meta');
  if RootNode = Nil then
   RootNode:=FMeta.CreateElement('office:meta');
   

   Node:=RootNode.FindNode('dc:description');
   Node.Free;// удаляем чтоб не плодить двойников с тэгом 'dc:description'
    if  AValue.Description<>'' then
       begin
       Node:=FMeta.CreateElement('dc:description');
       Node.TextContent:=AValue.Description;
       RootNode.AppendChild(Node);
       end;
FMeta.DocumentElement.AppendChild(RootNode);
end;

Но пройдясь по исходникам наткнулся на такую интересную вещь:

Код: Выделить всё

function TDOMNode.FindNode(const ANodeName: DOMString): TDOMNode;
begin
  // FIX: we have no children, hence cannot find anything
  Result := nil;
end;

Но вот почему же процедура работала? Далее пошел по пути FMeta.DocumentElement.FindNode('dc:description'); Где в исходниках видно, что действительно возвращаем Node:

Код: Выделить всё

function TDOMNode_WithChildren.FindNode(const ANodeName: DOMString): TDOMNode;
begin
  Result := FFirstChild;
  while Assigned(Result) do
  begin
    if Result.CompareName(ANodeName)=0 then
      Exit;
    Result := Result.NextSibling;
  end;
end;


Переписал процедуру вот так:

Код: Выделить всё

procedure TOODocument.SetMetaData(const AValue: TOOMetaData);
var RootNode,Node: TDOMNode;
    Exist:Boolean;
    I:Integer;
begin

 RootNode:=FMeta.DocumentElement.FindNode('office:meta');
  if RootNode = Nil then
   RootNode:=FMeta.CreateElement('office:meta');

  Exist:=False;
  for I:=0 to RootNode.ChildNodes.Count-1 do
   begin
     if RootNode.ChildNodes[I].NodeName='dc:description' then
     begin
        RootNode.ChildNodes[I].TextContent:=AValue.Description;
        Exist:=True;
        break;
     end;
   end;
RootNode.ChildNodes.Free;

   if Exist = False then
   begin
   Node:=FMeta.CreateElement('dc:description');
   Node.TextContent:=AValue.Description;
   RootNode.AppendChild(Node);
   end;
   FMeta.DocumentElement.AppendChild(RootNode);
End;

Тоже работает, так мне в первом случае просто магическим образом повезло? Или это ошибка была позднее закрыта? Или я что-то не понял?. Ведь по идее нужно работать через ChildNodes?
Lazarus ver 0.9.29 svn 26447
Последний раз редактировалось Maxizar 04.03.2011 20:50:59, всего редактировалось 1 раз.
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

А вы не задумывались, что TDOMNode.FindNode является виртуальным методом и перекрыт в потомках?

Добавлено спустя 45 секунд:
Кстати вы указали версию Lazarus, в данном случае хочется больше увидеть версию FPC!
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Сообщение Maxizar »

Ой... :oops: . Извиняюсь за баян...
Odyssey
энтузиаст
Сообщения: 580
Зарегистрирован: 29.11.2007 16:32:24

Сообщение Odyssey »

К слову, для своего проекта я написал модуль-расширение для работы с XML, чтобы вместо вот такого безобразия:

Код: Выделить всё

RootNode:=FMeta.DocumentElement.FindNode('office:meta');
  if RootNode = Nil then
  begin
    RootNode:=FMeta.CreateElement('office:meta');
    // ...
    FMeta.DocumentElement.AppendChild(RootNode);
  end;
делать так:

Код: Выделить всё

RootNode:=DomEnsureChild(FMeta.DocumentElement, 'office:meta');

Есть чтение/запись типизированных значений, работа с дочерними нодами и чтение/запись фрагментов XML.
Сейчас отправил запрос на добавление в Lazarus-CCR, но ответ пока не пришёл. Если кому-нибудь интересно, прикладываю архив.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Odyssey
Вряд ли добавят т.к. ваши функции не соответсвуют спецификации DOM.

ps Я думаю, что каждый, кто работает с XML написал подобный модуль... (по крайней мере у меня есть свой)
Odyssey
энтузиаст
Сообщения: 580
Зарегистрирован: 29.11.2007 16:32:24

Сообщение Odyssey »

Так эти функции и не претендуют на место в dom.pp, и даже в fcl-xml, это расширение. FindNode тоже нет в спецификации DOM. Впрочем, если не добавят -- не фатально. А насчёт "у каждого свой такой модуль" -- согласен. Причём это справедливо не только для FPC, для Java есть бесчисленные DOMUtils, чуть ли не у каждого проекта свои.
Ответить