Delphi бесплатный анализатор XML / Reader для файлов GPX - PullRequest
2 голосов
/ 02 декабря 2011

Я ищу бесплатный простой в использовании анализатор XML / Reader для файлов GPX в Delphi, и мне было интересно, может ли кто-нибудь порекомендовать его или я должен использовать собственную привязку данных XML / документ XML Delphi?

спасибо

Colin

Ответы [ 5 ]

3 голосов
/ 02 декабря 2011

Вы можете использовать инструмент «XML mapper» от Delphi.
Здесь, в моем блоге, вы можете найти статью «Загрузка файла GPX (XML) и доступ к данным», в которой объясняется, как использовать этот инструмент (XML Mapper). Пример создания структуры для загрузки файлов GPX.

enter image description here

Вы можете найти другие похожие посты, такие как "Генерировать маршруты файлов KML; Треки на Картах Google" , которые используют эти инструменты также для создания файлов KML.

Веб-страница первоначально на испанском языке, но вы можете использовать Google Translate (справа на странице). Также вы можете скачать исходный код примеров и посмотреть / протестировать его.

Привет.

3 голосов
/ 02 декабря 2011

NativeXml

Это компактная собственная реализация Delphi для чтения и записи документов XML.Он обеспечивает полностью объектно-ориентированный подход к работе с файлами XML с четко определенными и Delphi-ориентированными свойствами, событиями и методами.

Этот код можно использовать для чтения и записи документов XML из / в файлы, потокиили строки.Процедура загрузки генерирует события, которые можно использовать для отображения хода загрузки на лету.

Веб-сайт NativeXML

2 голосов
/ 02 декабря 2011

OmniXML

Это бесплатно ( MPL 1.1 ), достаточно быстро и реализует спецификацию DOM Level 1 плюс некоторые расширения MS.

В StackOverflow есть несколько примеров OmniXML .

1 голос
/ 04 декабря 2011

Альтернативный способ с TNativeXML .

Очевидно, что вы можете получить специализированный класс из TNativeXml, но в моем коде я использовал вспомогательный класс:

unit uHelper;

interface

uses
  SysUtils,
  Classes,
  NativeXml;

const
  // Do not localize these
  sNamespace  = 'http://www.topografix.com/GPX/1/1';
  sVersion = '1.1';
  sCreator = 'SwathGen';
  sSchemaInstance = 'http://www.w3.org/2001/XMLSchema-instance';
  sSchemaLocation = sNamespace+' '+
                    'http://www.topografix.com/GPX/1/1/gpx.xsd';

resourcestring
  sNoGpxRoot       = '<%s> has no gpx root !';
  sWrongGpxXmlns   = '<%s> root has a wrong xmlns attribute';
  sWrongGpxVersion = '<%s> is not a version "1.1" gpx file !';

type
  EGpxException = class(Exception)

  end;

type
  TGpxHelper = class helper for TNativeXml
  private
    function GetMetadataNode: TXmlNode;
    function GetWaypointNodes: TsdNodeList;
    function GetRouteNodes: TsdNodeList;
    function GetTrackNodes: TsdNodeList;
    function GetExtensionsNode: TXmlNode;
  public
    constructor CreateGpx(AOwner: TComponent);

    procedure NewGpx;

    procedure NodesAdd(ANodes: array of TXmlNode); overload;

    procedure AssignToStrings(AStrings:TStrings);

    function Element(const AName: string): TXmlNode;

    // File IO
    procedure LoadGpxFromFile(const AFileName: string);
    procedure SaveGpxToFile(const AFileName: string);

    property Metadata:TXmlNode read GetMetadataNode;
    property Waypoints:TsdNodeList read GetWaypointNodes;
    property Routes:TsdNodeList read GetRouteNodes;
    property Tracks:TsdNodeList read GetTrackNodes;
    property Extensions:TXmlNode read GetExtensionsNode;
  end;

  TGpxNodeHelper = class helper for TXmlNode
    function Element(const AName: string): TXmlNode;
  end;

implementation

{ TGpxHelper }

procedure TGpxHelper.AssignToStrings(AStrings:TStrings);
var
  lXmlFormat: TXmlFormatType;
  lIndentString: string;
begin
  // Save states
  lXmlFormat := XmlFormat;
  lIndentString := IndentString;

  XmlFormat := xfReadable;
  IndentString := '  ';

  AStrings.Text := WriteToString;

  // Restore states
  XmlFormat := lXmlFormat;
  IndentString := lIndentString;
end;

constructor TGpxHelper.CreateGpx(AOwner: TComponent);
begin
  inherited Create(AOwner);
  //
  NewGpx;
end;

function TGpxHelper.Element(const AName: string): TXmlNode;
begin
  Result := Root.Element(AName);
end;

function TGpxHelper.GetExtensionsNode: TXmlNode;
begin
  Result := Element('extensions');
end;

function TGpxHelper.GetMetadataNode: TXmlNode;
begin
  Result := Element('metadata');
end;

function TGpxHelper.GetRouteNodes: TsdNodeList;
begin
  Result := TsdNodeList.Create(False);

  Root.NodesByName('rte', Result);
end;

function TGpxHelper.GetTrackNodes: TsdNodeList;
begin
  Result := TsdNodeList.Create(False);

  Root.NodesByName('trk', Result);
end;

function TGpxHelper.GetWaypointNodes: TsdNodeList;
begin
  Result := TsdNodeList.Create(False);

  Root.NodesByName('wpt', Result);
end;

procedure TGpxHelper.LoadGpxFromFile(const AFileName: string);
var
  lGpx: TNativeXml;
  lFileName: TFileName;
begin
  lFileName := ExtractFileName(AFileName);

  lGpx := TNativeXml.Create(Self);

  lGpx.LoadFromFile(AFileName);

  try
    if lGpx.Root.Name<>'gpx' then
      raise EGpxException.CreateFmt(sNoGpxRoot,[lFileName])
    else if lGpx.Root.AttributeValue[Root.AttributeIndexByName('xmlns')]<>sNamespace then
      raise EGpxException.CreateFmt(sWrongGpxXmlns,[lFileName])
    else if lGpx.Root.AttributeValue[Root.AttributeIndexByName('version')]<>sVersion then
      raise EGpxException.CreateFmt(sWrongGpxVersion,[lFileName])
    else
      Self.ReadFromString(lGpx.WriteToString) // <<<
  finally
    lGpx.Free
  end;
end;

procedure TGpxHelper.NewGpx;
begin
  New;

  Root.Name := 'gpx';

  NodesAdd(
    [
      AttrText('xmlns', sNamespace),
      AttrText('version', sVersion),
      AttrText('creator', sCreator),
      AttrText('xmlns:xsi',sSchemaInstance),
      AttrText('xsi:schemaLocation', sSchemaLocation),

      // Metadata
      NodeNew('metadata',
        [
          NodeNewAttr('bounds',
            [
              AttrText('minlat','90.00000000'),
              AttrText('minlon','180.00000000'),
              AttrText('maxlat','-90.00000000'),
              AttrText('maxlon','-180.00000000')
            ]
          ),
          NodeNew('extensions')
        ]
      ),

      // Waypoints

      // Routes

      // Tracks

      NodeNew('extensions')
    ]
  );
end;

procedure TGpxHelper.NodesAdd(ANodes: array of TXmlNode);
begin
  Root.NodesAdd(ANodes);
end;

procedure TGpxHelper.SaveGpxToFile(const AFileName: string);
begin
  ChangeFileExt(AFileName,'gpx');

  SaveToFile(AFileName);  
end;

{ TGpxNodeHelper }

function TGpxNodeHelper.Element(const AName: string): TXmlNode;
begin
  Result := NodeByName(UTF8String(AName));
end;

end.

Практический образец с использованием устройства uHelper:

unit ufrmMain;

interface

uses
  NativeXml,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, SynEdit, SynMemo, SynEditHighlighter, SynHighlighterXML,
  SynEditMiscClasses, SynEditSearch, ComCtrls;

type
  TMainForm = class(TForm)
    BtnNew: TButton;
    BtnLoad: TButton;
    OpenDialog: TOpenDialog;
    BtnSave: TButton;
    SaveDialog: TSaveDialog;
    Memo: TSynMemo;
    XMLSyn: TSynXMLSyn;
    Search: TSynEditSearch;
    StatusBar: TStatusBar;
    procedure FormCreate(Sender: TObject);
    procedure BtnLoadClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure BtnSaveClick(Sender: TObject);
    procedure BtnNewClick(Sender: TObject);
  private
    FGpx: TNativeXml;

    procedure ShowGpxInfo;
    procedure UpdateControls;
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

uses
  Math,
  uHelper;

{$R *.dfm}

procedure TMainForm.BtnLoadClick(Sender: TObject);
begin
  OpenDialog.FileName := '';

  if OpenDialog.Execute then
  begin
    FGpx.LoadGpxFromFile(OpenDialog.FileName);

    UpdateControls;
    ShowGpxInfo
  end;
end;

procedure TMainForm.BtnNewClick(Sender: TObject);
begin
  FGpx.NewGpx;

  UpdateControls;
end;

procedure TMainForm.BtnSaveClick(Sender: TObject);
begin
  SaveDialog.FileName := '';

  if SaveDialog.Execute then
  begin
    FGpx.SaveGpxToFile(SaveDialog.FileName);
  end;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  FGpx := TNativeXml.CreateGpx(Self);
end;

procedure TMainForm.FormShow(Sender: TObject);
begin
  UpdateControls;
end;

procedure TMainForm.ShowGpxInfo;
const
  cLF = #10#13;
  cMsg  = 'metadata node count : %u'+cLF+
          'wpt node count : %u'+cLF+
          'rte node count : %u'+cLF+
          'trk node count : %u'+cLF+
          'extensions node count : %u';
var
  lMetadataCount: Integer;
  lWaypointsCount: Integer;
  lRoutesCount: Integer;
  lTracksCount: Integer;
  lExtensions: Integer;
begin
  lMetadataCount := IfThen(Assigned(FGpx.Metadata),1,0); 

  with FGpx.Waypoints do
  try
    lWaypointsCount := Count;
  finally
    Free
  end;

  with FGpx.Routes do
  try
    lRoutesCount := Count;
  finally
    Free
  end;

  with FGpx.Tracks do
  try
    lTracksCount := Count;
  finally
    Free
  end;

  lExtensions := IfThen(Assigned(FGpx.Extensions),1,0); 

  ShowMessage(Format(cMsg,[lMetadataCount,lWaypointsCount,lRoutesCount,lTracksCount,lExtensions]))
end;

procedure TMainForm.UpdateControls;
begin
  FGpx.AssignToStrings(Memo.Lines); // <<<
end;

end.
0 голосов
/ 04 декабря 2011

Вы можете использовать SimpleStorage .

Пример кода доступа к Gpx-файлу:

interface

uses
  ...
  Cromis.SimpleStorage, ...

type
  TMainForm = class(TForm)
    ...
    MmGpx: TMemo;
    BtnLoad: TButton;
    OpenDialog: TOpenDialog;
    ...
  private
    FGpxStorage: ISimpleStorage;
  protected
    procedure ShowGpx;
  end;

...

implementation

procedure TMainForm.BtnLoadClick(Sender: TObject);
begin
  if OpenDialog.Execute then
    FGpxStorage := StorageFromFile(OpenDialog.FileName); // <<<
    ShowGpx;
  end;
end;

procedure TMainForm.ShowGpx;
begin
  MmGpx.Lines.Text := FGpxStorage.Content(True); // <<<
end;

Более того, вы все еще можете найти здесь шаблон использования SimpleStorage для создания нового совместимого файла Gpx с нуля.

...