x2xmldatabinding/Units/XMLDataBindingGenerator.pas

199 lines
5.0 KiB
ObjectPascal

unit XMLDataBindingGenerator;
interface
uses
Classes,
Contnrs,
XMLSchema;
type
TXMLDataBindingSchema = class(TObject)
private
FSchemaDef: IXMLSchemaDef;
FSchemaName: String;
public
property SchemaDef: IXMLSchemaDef read FSchemaDef write FSchemaDef;
property SchemaName: String read FSchemaName write FSchemaName;
end;
TXMLDataBindingOutputType = (otSingle, otMultiple);
TXMLDataBindingGenerator = class(TObject)
private
FIncludePaths: TStrings;
FOutputPath: string;
FOutputType: TXMLDataBindingOutputType;
FSourceFileName: String;
FSchemas: TObjectList;
function GetSchemaCount(): Integer;
function GetSchema(Index: Integer): TXMLDataBindingSchema;
protected
function LoadSchema(const AStream: TStream; const ASchemaName: String): IXMLSchemaDef;
function FindSchema(const ALocation: String): TStream;
procedure GenerateDataBinding(); virtual; abstract;
property SourceFileName: String read FSourceFileName write FSourceFileName;
property SchemaCount: Integer read GetSchemaCount;
property Schema[Index: Integer]: TXMLDataBindingSchema read GetSchema;
public
constructor Create();
destructor Destroy(); override;
procedure Execute(const AStream: TStream; const ASchemaName: String); overload;
procedure Execute(const AFileName: String); overload;
property IncludePaths: TStrings read FIncludePaths;
property OutputType: TXMLDataBindingOutputType read FOutputType write FOutputType;
property OutputPath: string read FOutputPath write FOutputPath;
end;
implementation
uses
SysUtils,
XMLDoc,
XMLIntf;
{ TXMLDataBindingGenerator }
constructor TXMLDataBindingGenerator.Create();
begin
inherited;
FIncludePaths := TStringList.Create();
FSchemas := TObjectList.Create(True);
with TStringList(FIncludePaths) do
begin
CaseSensitive := False;
Duplicates := dupIgnore;
end;
end;
destructor TXMLDataBindingGenerator.Destroy();
begin
FreeAndNil(FSchemas);
FreeAndNil(FIncludePaths);
inherited;
end;
procedure TXMLDataBindingGenerator.Execute(const AStream: TStream; const ASchemaName: String);
//var
// schemaIndex: Integer;
//
begin
FSchemas.Clear();
LoadSchema(AStream, ASchemaName);
if SchemaCount > 0 then
GenerateDataBinding();
end;
procedure TXMLDataBindingGenerator.Execute(const AFileName: String);
var
currentDir: String;
fileStream: TFileStream;
begin
currentDir := GetCurrentDir();
try
ChDir(ExtractFilePath(AFileName));
fileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyNone);
try
FSourceFileName := AFileName;
IncludePaths.Add(ExtractFilePath(AFileName));
Execute(fileStream, ChangeFileExt(ExtractFileName(AFileName), ''));
finally
FreeAndNil(fileStream);
end;
finally
ChDir(currentDir);
end;
end;
function TXMLDataBindingGenerator.LoadSchema(const AStream: TStream; const ASchemaName: String): IXMLSchemaDef;
var
includeIndex: Integer;
includes: IXMLSchemaIncludes;
includeStream: TStream;
location: String;
schema: TXMLDataBindingSchema;
schemaDoc: IXMLSchemaDoc;
begin
schemaDoc := TXMLSchemaDoc.Create(nil);
schemaDoc.LoadFromStream(AStream);
Result := schemaDoc.SchemaDef;
schema := TXMLDataBindingSchema.Create();
schema.SchemaDef := Result;
schema.SchemaName := ASchemaName;
FSchemas.Add(schema);
{ Handle includes }
includes := Result.SchemaIncludes;
for includeIndex := 0 to Pred(includes.Count) do
begin
location := includes[includeIndex].SchemaLocation;
includeStream := FindSchema(location);
if Assigned(includeStream) then
try
location := ChangeFileExt(ExtractFileName(location), '');
LoadSchema(includeStream, location);
finally
FreeAndNil(includeStream);
end;
end;
end;
function TXMLDataBindingGenerator.FindSchema(const ALocation: String): TStream;
var
includeIndex: Integer;
includePath: String;
begin
Result := nil;
// #ToDo3 (MvR) 31-1-2007: support more locations than just a filename ?
for includeIndex := 0 to Pred(IncludePaths.Count) do
begin
includePath := IncludeTrailingPathDelimiter(IncludePaths[includeIndex]);
if FileExists(includePath + ALocation) then
begin
Result := TFileStream.Create(includePath + ALocation, fmOpenRead or fmShareDenyNone);
break;
end;
end;
end;
function TXMLDataBindingGenerator.GetSchemaCount(): Integer;
begin
Result := FSchemas.Count;
end;
function TXMLDataBindingGenerator.GetSchema(Index: Integer): TXMLDataBindingSchema;
begin
Result := TXMLDataBindingSchema(FSchemas[Index]);
end;
end.