Форум по программированию Delphi Sources

 



Вернуться   Форум по программированию Delphi Sources > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 07.04.2019, 12:36
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 738
Репутация: 1293
По умолчанию Парсинг XML

Приветствую, в XML не силен, нужно спарсить данные с файла сигнатур, набросал код с использование компонента SimpleXML, но выдает не все данные и с множеством пустых строк:

Код:
procedure TForm1.Button3Click(Sender: TObject);
var
  aDoc: IXmlDocument;
  anElem2: IXmlNode;
  rez: array of string;
  i: integer;

  procedure PrintNode(Node: IXmlNode);
  var
    str: string;
    j: word;
    NodeList: IXmlNodeList;
  begin
      Memo2.Lines.Add(trim(Node.GetAttr('name')));
    Memo2.Lines.Add(trim(Node.GetChildText('ext')));
    NodeList := Node.ChildNodes;
    if NodeList.Count > 0 then
      for j := 0 to NodeList.Count - 1 do
        PrintNode(NodeList.Item[j]);
  end;
begin
 //	Создаем пустой документ XML
  aDoc := CreateXmlDocument;
 //	Считываем из файла
  aDoc.Load(ExtractFilePath(ParamStr(0)) + '\mime-types.xml');
   PrintNode(aDoc);
end;

Код HTML:
-<mime-types> <!-- ! Application primary type ! --> -<mime-type name="application/andrew-inset"> <ext>ez</ext> </mime-type> -<mime-type name="text/html" description="Hypertext Markup Language (HTML)"> <ext>htm</ext> <ext>html</ext> <magic value="<HEAD" offset="0"/> <magic value="<head" offset="0"/> <magic value="<TITLE" offset="0"/> <magic value="<HEAD" offset="0"/> <magic value="<!doctype html" offset="0"/> <magic value="<!DOCTYPE HTML" offset="0"/> <magic value="<html" offset="0"/> <magic value="<HTML" offset="0"/> <magic value="<H1" offset="0"/> <magic value="<h1" offset="0"/> </mime-type>
Ответить с цитированием
  #2  
Старый 07.04.2019, 18:57
Аватар для lmikle
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,336
Версия Delphi: 7, XE3, 10.2
Репутация: 49088
По умолчанию

Вот через стандатрный TXMLDocument:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  doc : IXmlDocument;
  rootNode : IXMLNode;
  I,J : Integer;
begin
  Memo1.Lines.Clear;
  doc := TXMLDocument.Create(Nil);
  Try
    doc.LoadFromFile('c:\work\xml.xml');
    doc.Active := True;
    rootNode := doc.ChildNodes.FindNode('mime-types');
    for I := 0 To rootNode.ChildNodes.Count-1 Do
      If rootNode.ChildNodes[i].NodeName = 'mime-type' Then
        Begin
          Memo1.Lines.Add(rootNode.ChildNodes[i].Attributes['name']);
          For J := 0 To rootNode.ChildNodes[i].ChildNodes.Count-1 Do
            If rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'ext' Then
              Memo1.Lines.Add('  ' + rootNode.ChildNodes[i].ChildNodes[J].NodeValue);
        End;

  Finally
    doc := Nil;
  End;
end;

ЗЫ. Твой xml не правильный.
1. Он не закрыт (ну тут подозреваю, что ты просто скопировал только кусок.
2. Символ '<' недопустим внутри значения. Заменить на '&lt;'
3. Ну и тире убрать перед тегами mime-type (как я понял, это ты просто отметил типа корневые).

Последний раз редактировалось lmikle, 07.04.2019 в 19:01.
Ответить с цитированием
  #3  
Старый 08.04.2019, 10:09
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 738
Репутация: 1293
По умолчанию

Да, ты все правильно понял, насчет кода, проверю, отпишусь, пока накидал собственный парсер
Ответить с цитированием
  #4  
Старый 08.04.2019, 20:07
Аватар для lmikle
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,336
Версия Delphi: 7, XE3, 10.2
Репутация: 49088
По умолчанию

Дык эта, я ж на твоем примере и проверил.
Всего вывел 5 строк.
Ответить с цитированием
  #5  
Старый 09.04.2019, 19:51
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 738
Репутация: 1293
По умолчанию

Вот такие заморочки там встречаются, пытаюсь победить "offset", "type", "value":

Код HTML:
<?xml version="1.0" encoding="UTF-8"?> <mime-types> <mime-type name="application/andrew-inset"> <ext>ez</ext> </mime-type> <mime-type name="application/pdf" description="Portable Document Format (PDF)"> <ext>pdf</ext> <magic offset="0" value="%PDF-"/> </mime-type> <mime-type name="application/vnd.mif" description="FrameMaker Interchange Format"> <ext>mif</ext> <magic offset="0" type="byte" value="3c4d494646696c6520"/> </mime-type> <mime-type name="application/postscript" description="PostScript (PS)"> <ext>ps</ext><ext>ai</ext><ext>eps</ext> <magic offset="0" value="%!"/> <magic offset="0" value="\004%!"/> </mime-type> </mime-types>

Код:
procedure TForm1.Button4Click(Sender: TObject);
var
  doc: IXmlDocument;
  rootNode: IXMLNode;
  I, J: Integer;
  S: string;
begin
  Memo1.Lines.Clear;
  doc := TXMLDocument.Create(nil);
  try
    doc.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mime-types.xml');
    doc.Active := True;
    doc.ChildNodes.FindNode('mime-types');
    rootNode := doc.ChildNodes.FindNode('mime-types');
    if rootNode.ChildNodes.Count = 0 then
      EXIT;
    for I := 0 to rootNode.ChildNodes.Count - 1 do
    begin
      if rootNode.ChildNodes[i].NodeName = 'mime-type' then
      begin
        Memo2.Lines.Add(rootNode.ChildNodes[i].Attributes['name']);
        if rootNode.ChildNodes[i].HasAttribute('description') then//added
          Memo2.Lines.Add(rootNode.ChildNodes[i].Attributes['description']);//added
        for J := 0 to rootNode.ChildNodes[i].ChildNodes.Count - 1 do
        begin
          if rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'ext' then
            Memo2.Lines.Add('  ' + rootNode.ChildNodes[i].ChildNodes[J].NodeValue);
            //
//added, not worked
          if rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'magic' then
          begin
          if rootNode.ChildNodes[i].HasAttribute('offset') then
            s := rootNode.ChildNodes[i].Attributes['offset'];
            if rootNode.ChildNodes[i].HasAttribute('type') then
              s := S + '/' + rootNode.ChildNodes[i].Attributes['type'];
            if rootNode.ChildNodes[i].HasAttribute('value') then
              s := S + '/' + rootNode.ChildNodes[i].Attributes['value'];
            Memo2.Lines.Add(s);
          end;
          //
        end;
        Memo2.Lines.Add('------------------------------------');
      end;
    end;
  finally
    doc := nil;
  end;
end;
Ответить с цитированием
  #6  
Старый 10.04.2019, 01:05
Аватар для lmikle
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,336
Версия Delphi: 7, XE3, 10.2
Репутация: 49088
По умолчанию

Угу, не работает. Потому что у не того тега смотришь
Нужно:
Код:
...
         if rootNode.ChildNodes[i].ChildNodes[J].HasAttribute('offset') then
            s := rootNode.ChildNodes[i].ChildNodes[J].Attributes['offset'];
...
Ответить с цитированием
  #7  
Старый 10.04.2019, 12:14
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 738
Репутация: 1293
По умолчанию

Спасибо, выручил

Код:
procedure TForm1.Button4Click(Sender: TObject);
var
  doc: IXmlDocument;
  rootNode: IXMLNode;
  i, J: integer;
  s: string;
begin
  Memo2.Lines.Clear;
  doc := TXMLDocument.Create(nil);
  try
    doc.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mime-types.xml');
    doc.Active := true;
    doc.ChildNodes.FindNode('mime-types');
    rootNode := doc.ChildNodes.FindNode('mime-types');
    if rootNode.ChildNodes.Count = 0 then
      EXIT;
    for i := 0 to rootNode.ChildNodes.Count - 1 do
    begin
      if rootNode.ChildNodes[i].NodeName = 'mime-type' then
      begin
        Memo2.Lines.add(rootNode.ChildNodes[i].Attributes['name']);
        if rootNode.ChildNodes[i].HasAttribute('description') then
          Memo2.Lines.add(rootNode.ChildNodes[i].Attributes['description']);
        for J := 0 to rootNode.ChildNodes[i].ChildNodes.Count - 1 do
        begin
          if rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'ext' then
            Memo2.Lines.add('  ' + rootNode.ChildNodes[i].ChildNodes[J]
              .NodeValue);
          //
          if rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'magic' then
          begin
            s := '';
            if rootNode.ChildNodes[i].ChildNodes[J].HasAttribute('offset') then
              s := rootNode.ChildNodes[i].ChildNodes[J].Attributes['offset'];
            if rootNode.ChildNodes[i].ChildNodes[J].HasAttribute('type') then
              s := s + '/' + rootNode.ChildNodes[i].ChildNodes[J].Attributes['type'];
            if rootNode.ChildNodes[i].ChildNodes[J].HasAttribute('value') then
              s := s + '/' + rootNode.ChildNodes[i].ChildNodes[J].Attributes['value'];
            Memo2.Lines.add(s);
          end;
          //
        end;
        Memo2.Lines.add('------------------------------------');
      end;
    end;
  finally
    doc := nil;
  end;
end;
Ответить с цитированием
  #8  
Старый 10.04.2019, 19:38
Аватар для lmikle
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,336
Версия Delphi: 7, XE3, 10.2
Репутация: 49088
По умолчанию

Вообще, если xml большой, то рекомендую сделать временную переменную, что бы на каждой итерации не "разрешать" колбасу вида
rootNode.ChildNodes[i].ChildNodes[J]
Быстрее работать будет. Но это для реально больших файлов.
Ну а для очень больших уже придется искать SAX парсер. Там по другому надо код строить немного.
Ответить с цитированием
  #9  
Старый 11.04.2019, 10:31
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 738
Репутация: 1293
По умолчанию

ок, принял, спасибо
Ответить с цитированием
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 20:13.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources", 2004-2019

ВКонтакте   Facebook   Twitter