Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

JSON в RichMemo на Delphi и Pascal: как отобразить и отфильтровать JSON-данные в компоненте TRichMemo.

Delphi , Компоненты и Классы , TMemo и TRichEdit

 

В мире разработки на Delphi и Pascal часто возникает необходимость работы с данными в формате JSON. Представление JSON-данных в удобном для пользователя виде, например, в компоненте TRichMemo, может быть непростой задачей. В этой статье мы рассмотрим, как можно эффективно отображать и фильтровать JSON-данные в TRichMemo, а также предложим альтернативные подходы.

Проблема:

Как элегантно и эффективно отобразить JSON-строку в компоненте TRichMemo, обеспечив читаемость и возможность фильтрации данных? Особенно важно обеспечить отказоустойчивость при работе с поврежденными JSON-строками, чтобы избежать множества сообщений об ошибках.

Решение 1: Прямое отображение с форматированием

Самый простой подход - это распарсить JSON-строку и отформатировать ее для отображения в TRichMemo. Для парсинга JSON можно использовать библиотеку fcl-json, входящую в состав Free Pascal Component Library (FCL).

uses
  System.SysUtils,
  Classes,
  RichEdit,
  FpJson,
  JsonParser;

procedure DisplayJsonInRichMemo(JsonString: string; RichMemo: TRichMemo);
var
  JSONObject: TJSONObject;
  FormattedString: string;
begin
  RichMemo.Clear;
  try
    JSONObject := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(JsonString), 0) as TJSONObject;
    if JSONObject <> nil then
    begin
      // Форматируем JSON для читаемости
      FormattedString := JSONObject.Format(jfPrettyPrint or jfUseTabs);
      RichMemo.Lines.Text := FormattedString;
      JSONObject.Free;
    end;
  except
    on E: Exception do
    begin
      RichMemo.Lines.Add('Ошибка при парсинге JSON: ' + E.Message);
    end;
  end;
end;

В этом примере используется функция JSONObject.Format с флагами jfPrettyPrint и jfUseTabs для создания удобочитаемого представления JSON-данных. Блок try...except обеспечивает обработку исключений, возникающих при парсинге некорректного JSON.

Решение 2: Иерархическое отображение с использованием TTreeView

Для более структурированного представления JSON-данных можно использовать компонент TTreeView. Каждый узел дерева будет представлять собой ключ или элемент массива JSON.

uses
  System.SysUtils,
  Classes,
  TreeView,
  FpJson,
  JsonParser;

procedure DisplayJsonInTreeView(JsonString: string; TreeView: TTreeView);
var
  JSONObject: TJSONObject;
  JSONArray: TJSONArray;
  JsonValue: TJSONValue;
  i: Integer;

  procedure AddNode(ParentNode: TTreeNode; Key: string; Value: TJSONValue);
  var
    Node: TTreeNode;
  begin
    Node := TreeView.Items.AddChild(ParentNode, Key + ': ' + Value.ToString);
    Node.Data := Value; // Сохраняем TJSONValue для дальнейшей обработки
  end;

  procedure ProcessJSONObject(ParentNode: TTreeNode; JSONObject: TJSONObject);
  var
    KeyValuePair: TJSONPair;
  begin
    for KeyValuePair in JSONObject do
    begin
      AddNode(ParentNode, KeyValuePair.JsonString.ToString, KeyValuePair.JsonValue);
      if KeyValuePair.JsonValue is TJSONObject then
      begin
        ProcessJSONObject(TreeView.Items.AddChild(ParentNode, KeyValuePair.JsonString.ToString), TJSONObject(KeyValuePair.JsonValue));
      end
      else if KeyValuePair.JsonValue is TJSONArray then
      begin
        ProcessJSONArray(TreeView.Items.AddChild(ParentNode, KeyValuePair.JsonString.ToString), TJSONArray(KeyValuePair.JsonValue));
      end;
    end;
  end;

  procedure ProcessJSONArray(ParentNode: TTreeNode; JSONArray: TJSONArray);
  begin
    for i := 0 to JSONArray.Count - 1 do
    begin
      JsonValue := JSONArray.Items[i];
      AddNode(ParentNode, Format('[%d]', [i]), JsonValue);

      if JsonValue is TJSONObject then
      begin
        ProcessJSONObject(TreeView.Items.AddChild(ParentNode, Format('[%d]', [i])), TJSONObject(JsonValue));
      end
      else if JsonValue is TJSONArray then
      begin
        ProcessJSONArray(TreeView.Items.AddChild(ParentNode, Format('[%d]', [i])), TJSONArray(JsonValue));
      end;
    end;
  end;

begin
  TreeView.Items.Clear;
  try
    JSONObject := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(JsonString), 0) as TJSONObject;
    if JSONObject <> nil then
    begin
      ProcessJSONObject(nil, JSONObject);
      JSONObject.Free;
    end;
  except
    on E: Exception do
    begin
      TreeView.Items.Add.Text := 'Ошибка при парсинге JSON: ' + E.Message;
    end;
  end;
end;

Этот код рекурсивно обходит структуру JSON и создает соответствующие узлы в TTreeView. Данные TJSONValue сохраняются в свойстве Data узла, что позволяет получить доступ к исходным данным при выборе узла.

Решение 3: Фильтрация и отображение данных (как в запросе)

Для реализации фильтрации, как описано в запросе (например, поиск новостей о "Tesla"), необходимо:

  1. Распарсить JSON: Используйте fcl-json для преобразования JSON-строки в структуру данных (например, TJSONObject или TJSONArray).
  2. Создать структуру данных: Определите классы для представления данных (например, TSource, TArticle, TArticles как в примере кода).
  3. Реализовать фильтрацию: Напишите код, который будет обходить структуру данных и выбирать элементы, соответствующие критериям фильтрации (например, содержащие слово "Tesla" в заголовке или описании).
  4. Отформатировать результаты: Преобразуйте отфильтрованные данные в строку, пригодную для отображения в TRichMemo.
uses
  System.SysUtils,
  Classes,
  RichEdit,
  FpJson,
  JsonParser;

type
  TSource = class
    ID, Name: string;
  end;

  TArticle = class
    Source: TSource;
    Author, Title, Description, URL, URLToImage, PublishedAt, Content: string;
    destructor Destroy; override;
  end;

  TArticles = class
    constructor Create(const SourceText: string);
    destructor Destroy; override;
  private
    FArticles: TList;
  public
    property Articles: TList read FArticles;
  end;

constructor TArticles.Create(const SourceText: string);
var
  JSONObject: TJSONObject;
  JSONArray: TJSONArray;
  i: Integer;
  ArticleObject: TJSONObject;
  Article: TArticle;
begin
  FArticles := TList.Create;
  try
    JSONObject := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(SourceText), 0) as TJSONObject;
    if JSONObject <> nil then
    begin
      JSONArray := JSONObject.Get('articles') as TJSONArray;
      if JSONArray <> nil then
      begin
        for i := 0 to JSONArray.Count - 1 do
        begin
          ArticleObject := JSONArray.Items[i] as TJSONObject;
          if ArticleObject <> nil then
          begin
            Article := TArticle.Create;
            try
              Article.Title := ArticleObject.Get('title').Value;
              Article.Description := ArticleObject.Get('description').Value;
              Article.PublishedAt := ArticleObject.Get('publishedAt').Value;
              // TODO: Заполнить остальные поля
              FArticles.Add(Article);
            except
              Article.Free;
            end;
          end;
        end;
      end;
      JSONObject.Free;
    end;
  except
    on E: Exception do
    begin
      // Обработка ошибок
    end;
  end;
end;

destructor TArticles.Destroy;
var
  i: Integer;
begin
  for i := 0 to FArticles.Count - 1 do
  begin
    TArticle(FArticles[i]).Free;
  end;
  FArticles.Free;
  inherited;
end;

destructor TArticle.Destroy;
begin
  Source.Free;
  inherited;
end;

procedure FilterAndDisplayNews(JsonString: string; RichMemo: TRichMemo; SearchTerm: string);
var
  News: TArticles;
  Article: TArticle;
  i: Integer;
  DatePart: array[0..2] of string;
  FormattedDate: string;
begin
  RichMemo.Clear;
  News := TArticles.Create(JsonString);
  try
    for i := 0 to News.Articles.Count - 1 do
    begin
      Article := TArticle(News.Articles[i]);
      if (Pos(LowerCase(SearchTerm), LowerCase(Article.Title)) > 0) or
         (Pos(LowerCase(SearchTerm), LowerCase(Article.Description)) > 0) then
      begin
        // Форматируем дату
        DatePart := SplitString(StringReplace(Article.PublishedAt, 'T', ' ', [rfReplaceAll]), ['-', ' ']);
        if Length(DatePart) >= 3 then
        begin
          FormattedDate := DatePart[2] + '.' + DatePart[1] + '.' + DatePart[0];
        end else
        begin
          FormattedDate := 'Неизвестная дата';
        end;

        RichMemo.Lines.Add(FormattedDate + ' ' + Article.Title);
      end;
    end;
  finally
    News.Free;
  end;
end;

Этот пример демонстрирует базовый подход к фильтрации JSON-данных и их отображению в TRichMemo. Необходимо адаптировать код под конкретную структуру JSON и желаемый формат вывода.

Альтернативные решения:

  • Использование TWebBrowser (CEF4Delphi): Преобразование JSON в HTML и отображение его в компоненте TWebBrowser (с использованием CEF4Delphi) позволяет использовать возможности HTML и CSS для форматирования и стилизации данных. Это может быть полезно для отображения сложных данных с интерактивными элементами.
  • Компоненты сторонних разработчиков: Существуют коммерческие и бесплатные компоненты для работы с JSON, которые могут предлагать более продвинутые возможности отображения и фильтрации данных.
  • TListView: Хотя и упомянуто, что "TListView is hard to fill", с правильным подходом и использованием OwnerData = True, можно добиться высокой производительности и гибкости при отображении больших объемов данных.

Важные замечания:

  • Обработка ошибок: Всегда предусматривайте обработку исключений при работе с JSON, чтобы избежать неожиданных сбоев программы.
  • Кодировка: Убедитесь, что JSON-строка имеет правильную кодировку (UTF-8).
  • Оптимизация: При работе с большими объемами данных необходимо оптимизировать код для повышения производительности. Например, можно использовать потоки для параллельной обработки данных.
  • Безопасность: При работе с данными, полученными из внешних источников, необходимо соблюдать меры безопасности, чтобы предотвратить внедрение вредоносного кода.

Заключение:

Выбор оптимального решения для отображения JSON-данных в TRichMemo зависит от конкретных требований проекта. Прямое отображение с форматированием подходит для простых случаев, в то время как иерархическое отображение с использованием TTreeView обеспечивает более структурированное представление. Для реализации фильтрации необходимо разработать код, который будет обходить структуру данных и выбирать элементы, соответствующие критериям фильтрации. Альтернативные решения, такие как использование TWebBrowser или компонентов сторонних разработчиков, могут предложить более продвинутые возможности, но требуют дополнительных усилий по интеграции. Важно помнить об обработке ошибок, кодировке, оптимизации и безопасности при работе с JSON-данными.

Создано по материалам из источника по ссылке.

В статье рассматриваются способы отображения и фильтрации JSON-данных в компоненте TRichMemo на Delphi и Pascal, предлагая решения от простого форматирования до иерархического представления и фильтрации с использованием различных компонентов и библиотек.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: TMemo и TRichEdit ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 17:14:06
2025-11-04 18:00:36/0.01087498664856/0