2011-12-02 95 views
2

我要尋找一個免費的易於使用的XML解析器/讀者爲德爾福GPX文件,並想知道如果任何人都可以推薦一個或者我應該用Delphi自己的XML數據綁定來/ XML文件?德爾福免費XML解析器/讀者爲GPX文件

感謝

科林

+3

作爲一個XML解析器我建議你[OmniXML](http://www.omnixml.com/)。而對於你的問題的其他部分,我不知道任何庫直接GPX支持。我會自己解析它;) – TLama

+3

[GPX編輯器](http://sourceforge.net/projects/gpxeditor/)是一個用Delphi編寫的開源編輯器,另請參閱[help-to-create-gpx-file-與-的Delphi-7](http://stackoverflow.com/questions/5197716/help-to-create-gpx-file-with-delphi-7)。 –

+0

內建['TXMLDocument'](http://docwiki.embarcadero.com/VCL/en/XMLDoc.TXMLDocument)有什麼問題?從我的經驗來看,它似乎很好。 –

回答

3

您可以使用Delphi的工具「XML映射器」。
在我的博客上,you can find the article「加載GPX文件(XML)訪問數據」解釋瞭如何使用此工具(XML Mapper)。該示例創建結構來加載GPX文件。

enter image description here

你可以找到其他類似的帖子,這樣"Generate KML files routes; Tracks on Google Maps"使用此工具還生成KML文件。

的網頁是淵源於西班牙,但是你可以使用谷歌翻譯(在頁面的右邊)。您也可以下載樣本的源代碼並查看/測試它。

問候。

+0

感謝您提供的信息,我注意到我可以使用XML Mapper執行此操作,然後保存佈局作爲XSD或DTD文件,然後將其加載到XML數據綁定向導中,以創建一個數據綁定作爲一個單元,而不是加載一個單獨的XTR文件,但我真的確信XML Mapper和數據綁定向導在Delphi 7中工作正常嗎?如果使用這種方法EG DLL,還有其他文件需要包含來分發項目嗎?謝謝 – colin

+0

我在這個示例中使用ClientDataset來加載導入的數據。在這種情況下,您可以將MIDAS.DLL添加到項目中。就這些。 –

3

NativeXml

這是一個小巧的本地Delphi實現讀寫XML文檔。它提供了一個完全面向對象的方法來處理XML文件,具有明確定義和Delphi專注的屬性,事件和方法。

您可以使用此代碼從/讀寫XML文檔文件,流或字符串。加載例程生成可用於顯示加載進度的事件。

NativeXML Website

+0

這是免費的(新的BSD許可證),並自8月份以來[Google Code](http://simdesign.googlecode.com)承載 – mjn

0

您可以使用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文件的模板。

1

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.