我正在为Delphi中的GPX文件寻找一个易于使用的XML解析器/ Reader,并且想知道是否有人可以推荐一个或者我应该使用Delphi自己的XML数据绑定/ XML文档?
感谢
科林
答案 0 :(得分:3)
NativeXml
这是一个用于读写XML文档的小型本机Delphi实现。它提供了一种完全面向对象的方法来处理XML文件,具有明确定义的和以Delphi为重点的属性,事件和方法。
您可以使用此代码从/向文件,流或字符串读取和写入XML文档。加载例程生成可用于动态显示加载进度的事件。
答案 1 :(得分:3)
您可以使用Delphi的工具“XML mapper” 在我的博客上,you can find the article“加载GPX文件(XML)和数据访问”,解释了如何使用此工具(XML Mapper)。示例创建结构以加载GPX文件。
您可以找到其他类似帖子,例如使用此工具生成KML文件的"Generate KML files routes; Tracks on Google Maps"。
该网页最初是西班牙语,但您可以使用Google翻译(在页面右侧)。您也可以下载样本的源代码并查看/测试它。
问候。
答案 2 :(得分:2)
答案 3 :(得分: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.
答案 4 :(得分: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文件。