1
0
mirror of synced 2024-06-26 05:47:39 +00:00
x2xmldatabinding/Units/XMLDataBindingGenerator.pas

228 lines
5.6 KiB
ObjectPascal
Raw Normal View History

2008-02-20 06:52:00 +00:00
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;
2008-02-26 21:53:11 +00:00
function SchemaLoaded(const ALocation: String): Boolean;
2008-02-20 06:52:00 +00:00
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;
2008-02-26 21:53:11 +00:00
procedure HandleDocRefs(const ADocRefs: IXMLSchemaDocRefs);
var
location: String;
refIndex: Integer;
refStream: TStream;
begin
for refIndex := 0 to Pred(ADocRefs.Count) do
begin
location := ADocRefs[refIndex].SchemaLocation;
if not SchemaLoaded(ChangeFileExt(location, '')) then
begin
refStream := FindSchema(location);
if Assigned(refStream) then
try
location := ChangeFileExt(ExtractFileName(location), '');
LoadSchema(refStream, location);
finally
FreeAndNil(refStream);
end;
end;
end;
end;
2008-02-20 06:52:00 +00:00
var
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);
2008-02-26 21:53:11 +00:00
{ Handle imports / includes }
HandleDocRefs(Result.SchemaImports);
HandleDocRefs(Result.SchemaIncludes);
2008-02-20 06:52:00 +00:00
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;
2008-02-26 21:53:11 +00:00
function TXMLDataBindingGenerator.SchemaLoaded(const ALocation: String): Boolean;
var
schemaIndex: Integer;
begin
Result := False;
for schemaIndex := 0 to Pred(SchemaCount) do
if Schema[schemaIndex].SchemaName = ALocation then
begin
Result := True;
break;
end;
end;
2008-02-20 06:52:00 +00:00
function TXMLDataBindingGenerator.GetSchemaCount(): Integer;
begin
Result := FSchemas.Count;
end;
function TXMLDataBindingGenerator.GetSchema(Index: Integer): TXMLDataBindingSchema;
begin
Result := TXMLDataBindingSchema(FSchemas[Index]);
end;
end.