x2xmldatabinding/Units/DelphiXMLDataBindingGenerat...

203 lines
5.7 KiB
ObjectPascal

unit DelphiXMLDataBindingGenerator;
interface
uses
Classes,
XMLSchema,
XMLDataBindingGenerator,
XMLDataBindingHelpers;
type
TGetFileNameEvent = procedure(Sender: TObject; const SchemaName: String; var Result: String) of object;
TDelphiXMLDataBindingGenerator = class(TXMLDataBindingGenerator)
private
FOnGetFileName: TGetFileNameEvent;
protected
procedure GenerateDataBinding(); override;
procedure GenerateSingleDataBinding();
procedure GenerateMultipleDataBinding();
function DoGetFileName(const ASchemaName: String): String;
procedure WriteUnitHeader(AStream: TStreamHelper; const AFileName: String);
procedure WriteSchemaInterfaces(AStream: TStreamHelper; ASchemaDef: IXMLSchemaDef; AForward: Boolean);
procedure WriteElementInterface(AStream: TStreamHelper; AElement: IXMLElementDef; AForward: Boolean);
procedure WriteElements(AStream: TStreamHelper; AType: IXMLTypeDef);
procedure WriteImplementation(AStream: TStreamHelper);
procedure WriteUnitFooter(AStream: TStreamHelper);
public
property OnGetFileName: TGetFileNameEvent read FOnGetFileName write FOnGetFileName;
end;
implementation
uses
SysUtils;
{ TDelphiXMLDataBindingGenerator }
procedure TDelphiXMLDataBindingGenerator.GenerateDataBinding();
begin
case OutputType of
otSingle: GenerateSingleDataBinding();
otMultiple: GenerateMultipleDataBinding();
end;
end;
procedure TDelphiXMLDataBindingGenerator.GenerateSingleDataBinding();
var
unitName: String;
unitStream: TStreamHelper;
schemaIndex: Integer;
begin
unitName := DoGetFileName(Schema[0].SchemaName);
unitStream := TStreamHelper.Create(TFileStream.Create(unitName, fmCreate), soOwned);
try
WriteUnitHeader(unitStream, unitName);
unitStream.WriteLn('type');
for schemaIndex := 0 to Pred(SchemaCount) do
begin
unitStream.WriteLn(' { Forward declarations for ' + Schema[schemaIndex].SchemaName + ' }');
WriteSchemaInterfaces(unitStream, Schema[schemaIndex].SchemaDef, True);
end;
for schemaIndex := 0 to Pred(SchemaCount) do
begin
unitStream.WriteLn(' { Interfaces for ' + Schema[schemaIndex].SchemaName + ' }');
WriteSchemaInterfaces(unitStream, Schema[schemaIndex].SchemaDef, False);
end;
WriteImplementation(unitStream);
WriteUnitFooter(unitStream);
finally
FreeAndNil(unitStream);
end;
end;
procedure TDelphiXMLDataBindingGenerator.GenerateMultipleDataBinding();
begin
end;
procedure TDelphiXMLDataBindingGenerator.WriteUnitHeader(AStream: TStreamHelper; const AFileName: String);
begin
// #ToDo1 (MvR) 14-4-2007: if outputtype = multiple, use include files
AStream.WriteLn('{');
AStream.WriteLn(' X2Software XML Data Binding Wizard');
AStream.WriteLn(' Generated from: ' + SourceFileName);
AStream.WriteLn('}');
AStream.WriteLn('unit ' + ChangeFileExt(ExtractFileName(AFileName), '') + ';');
AStream.WriteLn();
AStream.WriteLn('interface');
AStream.WriteLn('uses');
AStream.WriteLn(' XMLDoc,');
AStream.WriteLn(' XMLIntf;');
AStream.WriteLn();
end;
procedure TDelphiXMLDataBindingGenerator.WriteSchemaInterfaces(AStream: TStreamHelper; ASchemaDef: IXMLSchemaDef; AForward: Boolean);
procedure ProcessElementDefs(AElements: IXMLElementDefList);
var
elementIndex: Integer;
element: IXMLElementDef;
begin
for elementIndex := 0 to Pred(AElements.Count) do
begin
element := AElements[elementIndex];
if element.DataType.IsComplex then
begin
WriteElementInterface(AStream, element, AForward);
ProcessElementDefs(element.ChildElements);
end;
end;
end;
var
elementIndex: Integer;
element: IXMLElementDef;
complexTypeIndex: Integer;
complexType: IXMLComplexTypeDef;
begin
for elementIndex := 0 to Pred(ASchemaDef.ElementDefs.Count) do
begin
element := ASchemaDef.ElementDefs[elementIndex];
WriteElementInterface(AStream, element, AForward);
if element.DataType.IsComplex then
begin
ProcessElementDefs(element.ChildElements);
end;
end;
for complexTypeIndex := 0 to Pred(ASchemaDef.ComplexTypes.Count) do
begin
complexType := ASchemaDef.ComplexTypes[complexTypeIndex];
if AForward then
begin
AStream.WriteLn(' IXML' + complexType.Name + ' = interface; { ComplexType }');
end else
begin
AStream.WriteLn(' IXML' + complexType.Name + ' = interface');
AStream.WriteLn(' {TODO:GUID}');
WriteElements(complexType);
AStream.WriteLn(' end;');
AStream.WriteLn();
end;
ProcessElementDefs(complexType.ElementDefList);
end;
end;
procedure TDelphiXMLDataBindingGenerator.WriteElementInterface(AStream: TStreamHelper; AElement: IXMLElementDef; AForward: Boolean);
begin
if AForward then
begin
AStream.WriteLn(' IXML' + AElement.Name + ' = interface; { ElementDef }');
end else
begin
// #ToDo1 (MvR) 14-4-2007: output element interface
end;
end;
procedure TDelphiXMLDataBindingGenerator.WriteImplementation(AStream: TStreamHelper);
begin
end;
procedure TDelphiXMLDataBindingGenerator.WriteUnitFooter(AStream: TStreamHelper);
begin
AStream.WriteLn();
AStream.WriteLn('end.');
end;
function TDelphiXMLDataBindingGenerator.DoGetFileName(const ASchemaName: String): String;
begin
Result := OutputPath;
if OutputType = otMultiple then
begin
Result := IncludeTrailingPathDelimiter(Result) + ASchemaName + '.pas';
if Assigned(FOnGetFileName) then
FOnGetFileName(Self, ASchemaName, Result);
end;
end;
end.