【问题标题】:Delphi free XML parser / Reader for GPX filesDelphi 免费的 XML 解析器/GPX 文件阅读器
【发布时间】:2011-12-04 23:02:30
【问题描述】:

我正在为 Delphi 中的 GPX 文件寻找一个免费且易于使用的 XML 解析器/阅读器,并且想知道是否有人可以推荐一个或者我应该使用 Delphi 自己的 XML 数据绑定/XML 文档?

谢谢

科林

【问题讨论】:

  • 作为 XML 解析器,我向您推荐 OmniXML。对于您问题的另一部分,我不知道任何直接支持 GPX 的库。我会自己解析它;)
  • GPX Editor 是一个用 Delphi 编写的开源编辑器,另见 help-to-create-gpx-file-with-delphi-7
  • 内置的TXMLDocument有什么问题?根据我的经验,它似乎工作正常。

标签: xml delphi parsing gpx


【解决方案1】:

您可以使用Delphi的“XML映射器”工具。
在我的博客上,you can find the article“加载 GPX 文件 (XML) y 访问数据”解释了如何使用这个工具(XML 映射器)。示例创建结构以加载 GPX 文件。

您可以找到其他类似的帖子,例如 "Generate KML files routes; Tracks on Google Maps",它也使用此工具生成 KML 文件。

该网页最初是西班牙语,但您可以使用谷歌翻译(在页面右侧)。您也可以下载示例的源代码并查看/测试它。

问候。

【讨论】:

  • 感谢您提供的信息,我注意到我可以使用 XML 映射器执行此操作,然后将布局保存为 XSD 或 DTD 文件,然后将其加载到 XML 数据绑定向导中以创建数据绑定作为单元而不是加载单独的 XTR 文件,我真的要确保 XML 映射器和数据绑定向导在 Delphi 7 中正常工作?如果使用这种方法 EG DLL,我还需要包含任何其他文件来分发项目吗?谢谢
  • 我在这个示例中使用了一个 ClientDataset 来加载导入的数据。在这种情况下,您可以将 MIDAS.DLL 添加到项目中。就是这样。
【解决方案2】:

NativeXml

这是一个用于读取和写入 XML 文档的小型原生 Delphi 实现。它提供了一种完全面向对象的方法来处理 XML 文件,具有明确定义且以 Delphi 为中心的属性、事件和方法。

您可以使用此代码从文件、流或字符串读取和写入 XML 文档。加载例程生成可用于动态显示加载进度的事件。

NativeXML Website

【讨论】:

  • 它是免费的(新 BSD 许可证),并且自 8 月起托管在 Google Code
【解决方案3】:

OmniXML

它是免费的 (MPL 1.1),速度相当快,并且实现了 DOM Level 1 规范以及一些 MS 扩展。

StackOverflow 上有一些OmniXML examples

【讨论】:

    【解决方案4】:

    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.
    

    【讨论】:

      【解决方案5】:

      您可以使用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;
      

      此外,您还可以找到here 使用SimpleStorage 从头开始​​生成符合要求的新Gpx 文件的模板。

      【讨论】:

        猜你喜欢
        • 2011-02-28
        • 2012-01-28
        • 1970-01-01
        • 1970-01-01
        • 2012-01-29
        • 2012-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多