1
0
mirror of synced 2024-11-23 06:03:50 +00:00

Changed: hints file now uses XPath expressions

This commit is contained in:
Mark van Renswoude 2008-05-14 13:30:54 +00:00
parent 4238ee102e
commit fd9c309309
5 changed files with 516 additions and 118 deletions

Binary file not shown.

View File

@ -62,12 +62,9 @@ type
procedure feSchemaPropertiesChange(Sender: TObject); procedure feSchemaPropertiesChange(Sender: TObject);
procedure btnHintsClick(Sender: TObject); procedure btnHintsClick(Sender: TObject);
private private
FHints: IXMLDataBindingHints;
FHintsXPath: IDOMNodeSelect;
function CheckValidSchemaFile(): Boolean; function CheckValidSchemaFile(): Boolean;
function CheckReadOnly(const AFileName: String): Boolean;
procedure PostProcessItem(Sender: TObject; Item: TXMLDataBindingItem);
procedure GetFileName(Sender: TObject; const SchemaName: String; var Path, FileName: String); procedure GetFileName(Sender: TObject; const SchemaName: String; var Path, FileName: String);
function GetSettingsFileName(const AFileName: String): String; function GetSettingsFileName(const AFileName: String): String;
@ -91,15 +88,26 @@ uses
DelphiXMLDataBindingGenerator; DelphiXMLDataBindingGenerator;
const type
XPathHintBase = '/d:DataBindingHints'; TProtectedXMLDataBindingItem = class(TXMLDataBindingItem);
XPathHintEnumerationMember = XPathHintBase + '/d:Enumerations' + THintsDelphiXMLDataBindingGenerator = class(TDelphiXMLDataBindingGenerator)
'/d:Enumeration[@Name=''%<Enumeration>:s'']' + private
'/d:Member[@Name=''%<Member>:s'']/text()'; FHints: IXMLDataBindingHints;
protected
procedure GenerateDataBinding; override;
XPathHintDocumentElement = XPathHintBase + '/d:DocumentElements' + procedure ProcessHints;
'/d:DocumentElement[@Name=''%<Name>:s'']';
procedure ProcessEnumerations;
procedure ProcessDocumentElements;
procedure ProcessInterfaces;
function FindSchema(const ASchemaName: String; out ASchema: TXMLDataBindingSchema): Boolean;
function FindNode(const ASchemaName, AXPath: String; out AItem: TXMLDataBindingItem): Boolean;
public
property Hints: IXMLDataBindingHints read FHints write FHints;
end;
{$R *.dfm} {$R *.dfm}
@ -142,7 +150,8 @@ end;
procedure TMainForm.btnGenerateClick(Sender: TObject); procedure TMainForm.btnGenerateClick(Sender: TObject);
var var
hintsFile: String; hintsFile: String;
domDocument: IXMLDOMDocument2; hints: IXMLDataBindingHints;
generator: THintsDelphiXMLDataBindingGenerator;
begin begin
if not CheckValidSchemaFile() then if not CheckValidSchemaFile() then
@ -150,43 +159,37 @@ begin
hintsFile := ChangeFileExt(feSchema.Text, '.hints.xml'); hintsFile := ChangeFileExt(feSchema.Text, '.hints.xml');
if FileExists(hintsFile) then if FileExists(hintsFile) then
begin hints := LoadDataBindingHints(hintsFile);
FHints := LoadDataBindingHints(hintsFile);
{ Set the default namespace for XPath expressions to work }
domDocument := ((FHints.OwnerDocument.DOMDocument as IXMLDOMNodeRef).GetXMLDOMNode as IXMLDOMDocument2);
domDocument.setProperty('SelectionLanguage', 'XPath');
domDocument.setProperty('SelectionNamespaces', 'xmlns:d="' + DataBindingHintsXML.TargetNamespace + '"');
FHintsXPath := (FHints.OwnerDocument.DocumentElement.DOMNode as IDOMNodeSelect);
end;
try try
with TDelphiXMLDataBindingGenerator.Create() do generator := THintsDelphiXMLDataBindingGenerator.Create();
try try
generator.Hints := hints;
if rbFile.Checked then if rbFile.Checked then
begin begin
OutputType := otSingle; if not CheckReadOnly(feFile.Text) then
OutputPath := feFile.Text; Exit;
generator.OutputType := otSingle;
generator.OutputPath := feFile.Text;
end else if rbFolder.Checked then end else if rbFolder.Checked then
begin begin
OutputType := otMultiple; generator.OutputType := otMultiple;
OutputPath := deFolder.Text; generator.OutputPath := deFolder.Text;
end; end;
OnPostProcessItem := PostProcessItem; generator.OnGetFileName := GetFileName;
OnGetFileName := GetFileName; generator.Execute(feSchema.Text);
Execute(feSchema.Text);
SaveSettings(feSchema.Text); SaveSettings(feSchema.Text);
ShowMessage('The data binding has been generated.'); ShowMessage('The data binding has been generated.');
finally finally
Free(); FreeAndNil(generator);
end; end;
finally finally
FHints := nil; hints := nil;
FHintsXPath := nil;
end; end;
end; end;
@ -197,37 +200,6 @@ begin
end; end;
procedure TMainForm.PostProcessItem(Sender: TObject; Item: TXMLDataBindingItem);
var
member: TXMLDataBindingEnumerationMember;
hint: IDOMNode;
begin
if not Assigned(FHintsXPath) then
Exit;
if Item.ItemType = itEnumerationMember then
begin
{ Check if a hint for a new name is available }
member := TXMLDataBindingEnumerationMember(Item);
hint := FHintsXPath.selectNode(NamedFormat(XPathHintEnumerationMember,
['Enumeration', member.Enumeration.Name,
'Member', member.Name]));
if Assigned(hint) and (Length(hint.nodeValue) > 0) then
Item.TranslatedName := hint.nodeValue;
end;
if Item.ItemType = itInterface then
begin
if FHints.HasDocumentElements then
Item.DocumentElement := Assigned(FHintsXPath.selectNode(NamedFormat(XPathHintDocumentElement,
['Name', Item.Name])));
end;
end;
procedure TMainForm.GetFileName(Sender: TObject; const SchemaName: String; var Path, FileName: String); procedure TMainForm.GetFileName(Sender: TObject; const SchemaName: String; var Path, FileName: String);
begin begin
FileName := ChangeFileExt(edtFolderPrefix.Text + FileName, FileName := ChangeFileExt(edtFolderPrefix.Text + FileName,
@ -354,6 +326,24 @@ begin
'Schema file does not exist', MB_OK or MB_ICONERROR); 'Schema file does not exist', MB_OK or MB_ICONERROR);
ActiveControl := feFile; ActiveControl := feFile;
Exit;
end;
end;
function TMainForm.CheckReadOnly(const AFileName: String): Boolean;
begin
Result := True;
if FileExists(AFileName) and FileIsReadOnly(AFileName) then
begin
if MessageBox(Self.Handle, 'The output file is read-only. Do you want to ' +
'remove the read-only attribute?',
'Read-only', MB_YESNO or MB_ICONQUESTION) = ID_YES then
begin
Result := FileSetReadOnly(AFileName, False);
end else
Result := False;
end; end;
end; end;
@ -380,6 +370,227 @@ begin
end; end;
end; end;
{ THintsDelphiXMLDataBindingGenerator }
procedure THintsDelphiXMLDataBindingGenerator.GenerateDataBinding;
begin
if Assigned(Hints) then
ProcessHints;
inherited GenerateDataBinding;
end;
procedure THintsDelphiXMLDataBindingGenerator.ProcessHints;
begin
if Hints.HasEnumerations then
ProcessEnumerations;
if Hints.HasDocumentElements then
ProcessDocumentElements;
if Hints.HasInterfaces then
ProcessInterfaces;
end;
procedure THintsDelphiXMLDataBindingGenerator.ProcessEnumerations;
var
itemIndex: Integer;
enumeration: IXMLEnumeration;
schemaItem: TXMLDataBindingItem;
enumerationItem: TXMLDataBindingEnumeration;
hintMemberIndex: Integer;
memberName: String;
memberIndex: Integer;
begin
for itemIndex := 0 to Pred(Hints.Enumerations.Count) do
begin
enumeration := Hints.Enumerations[itemIndex];
if FindNode(enumeration.Schema, enumeration.XPath, schemaItem) and
(schemaItem.ItemType = itEnumeration) then
begin
enumerationItem := TXMLDataBindingEnumeration(schemaItem);
for hintMemberIndex := 0 to Pred(enumeration.Count) do
begin
memberName := enumeration.Member[hintMemberIndex].Name;
for memberIndex := 0 to Pred(enumerationItem.MemberCount) do
begin
if enumerationItem.Members[memberIndex].Name = memberName then
begin
enumerationItem.Members[memberIndex].TranslatedName := enumeration[hintMemberIndex].Text;
Break;
end;
end;
end;
end;
end;
end;
procedure THintsDelphiXMLDataBindingGenerator.ProcessDocumentElements;
var
schemaIndex: Integer;
schema: TXMLDataBindingSchema;
itemIndex: Integer;
documentElement: IXMLDocumentElement;
schemaItem: TXMLDataBindingItem;
begin
for schemaIndex := 0 to Pred(SchemaCount) do
begin
schema := Schemas[schemaIndex];
for itemIndex := 0 to Pred(schema.ItemCount) do
schema.Items[itemIndex].DocumentElement := False;
end;
for itemIndex := 0 to Pred(Hints.DocumentElements.Count) do
begin
documentElement := Hints.DocumentElements[itemIndex];
if FindNode(documentElement.Schema, documentElement.XPath, schemaItem) then
begin
if schemaItem.ItemType = itInterface then
schemaItem.DocumentElement := True;
end;
end;
end;
procedure THintsDelphiXMLDataBindingGenerator.ProcessInterfaces;
var
itemIndex: Integer;
interfaceName: IXMLInterfaceName;
schemaItem: TXMLDataBindingItem;
begin
for itemIndex := 0 to Pred(Hints.Interfaces.Count) do
begin
interfaceName := Hints.Interfaces[itemIndex];
if FindNode(interfaceName.Schema, interfaceName.XPath, schemaItem) then
begin
if schemaItem.ItemType in [itInterface, itEnumeration] then
schemaItem.TranslatedName := interfaceName.Text;
end;
end;
end;
function THintsDelphiXMLDataBindingGenerator.FindSchema(const ASchemaName: String; out ASchema: TXMLDataBindingSchema): Boolean;
var
schemaIndex: Integer;
begin
Result := False;
if SchemaCount > 0 then
begin
if Length(ASchemaName) = 0 then
begin
ASchema := Schemas[0];
Result := True;
end else
begin
for schemaIndex := 0 to Pred(SchemaCount) do
if SameText(Schemas[schemaIndex].SchemaName, ASchemaName) then
begin
ASchema := Schemas[schemaIndex];
Result := True;
Break;
end;
end;
end;
end;
function THintsDelphiXMLDataBindingGenerator.FindNode(const ASchemaName, AXPath: String; out AItem: TXMLDataBindingItem): Boolean;
function SameNode(ANode1, ANode2: IDOMNode): Boolean;
var
attributeIndex: Integer;
attribute1: IDOMNode;
attribute2: IDOMNode;
hasParent1: Boolean;
hasParent2: Boolean;
begin
{ Compare name and number of attributes }
Result := (ANode1.nodeName = ANode2.nodeName) and
(ANode1.attributes.length = ANode2.attributes.length);
if Result then
begin
{ Compare attribute content }
for attributeIndex := 0 to Pred(ANode1.attributes.length) do
begin
attribute1 := ANode1.attributes[attributeIndex];
attribute2 := ANode2.attributes[attributeIndex];
Result := (attribute1.nodeName = attribute2.nodeName) and
(attribute1.nodeValue = attribute2.nodeValue);
if not Result then
Break;
end;
if Result then
begin
{ Compare parent nodes }
hasParent1 := Assigned(ANode1.parentNode) and (ANode1.parentNode.nodeType <> NODE_DOCUMENT);
hasParent2 := Assigned(ANode2.parentNode) and (ANode2.parentNode.nodeType <> NODE_DOCUMENT);
if hasParent1 = hasParent2 then
begin
if hasParent1 then
Result := SameNode(ANode1.parentNode, ANode2.parentNode);
end else
Result := False;
end;
end;
end;
var
schema: TXMLDataBindingSchema;
schemaItem: IDOMNode;
item: TProtectedXMLDataBindingItem;
itemIndex: Integer;
domDocument: IXMLDOMDocument2;
begin
Result := False;
if (Length(AXPath) > 0) and FindSchema(ASchemaName, schema) then
begin
domDocument := ((schema.SchemaDef.OwnerDocument.DOMDocument as IXMLDOMNodeRef).GetXMLDOMNode as IXMLDOMDocument2);
domDocument.setProperty('SelectionLanguage', 'XPath');
domDocument.setProperty('SelectionNamespaces', 'xmlns:xs="http://www.w3.org/2001/XMLSchema"');
schemaItem := (schema.SchemaDef.DOMNode as IDOMNodeSelect).selectNode(AXPath);
if Assigned(schemaItem) then
begin
for itemIndex := 0 to Pred(schema.ItemCount) do
begin
item := TProtectedXMLDataBindingItem(schema.Items[itemIndex]);
if Assigned(item.SchemaItem) and SameNode(item.SchemaItem.DOMNode, schemaItem) then
begin
AItem := schema.Items[itemIndex];
Result := True;
Break;
end;
end;
end;
end;
end;
end. end.

View File

@ -1,7 +1,7 @@
{ {
X2Software XML Data Binding X2Software XML Data Binding
Generated on: 25-4-2008 10:37:37 Generated on: 14-5-2008 11:21:00
Generated from: P:\test\XMLDataBinding\XSD\DataBindingHints.xsd Generated from: P:\test\XMLDataBinding\XSD\DataBindingHints.xsd
} }
unit DataBindingHintsXML; unit DataBindingHintsXML;
@ -20,26 +20,32 @@ type
IXMLMember = interface; IXMLMember = interface;
IXMLDocumentElements = interface; IXMLDocumentElements = interface;
IXMLDocumentElement = interface; IXMLDocumentElement = interface;
IXMLInterfaces = interface;
IXMLInterfaceName = interface;
{ Interfaces for DataBindingHints } { Interfaces for DataBindingHints }
{ {
Contains hints and mappings for the data binding output Contains hints and mappings for the data binding output
} }
IXMLDataBindingHints = interface(IXMLNode) IXMLDataBindingHints = interface(IXMLNode)
['{33A3ED30-3F1C-4607-A848-D3F17297687F}'] ['{D2B7C152-7F8F-4B0F-9270-7330351B8D4E}']
function GetHasEnumerations: Boolean; function GetHasEnumerations: Boolean;
function GetEnumerations: IXMLEnumerations; function GetEnumerations: IXMLEnumerations;
function GetHasDocumentElements: Boolean; function GetHasDocumentElements: Boolean;
function GetDocumentElements: IXMLDocumentElements; function GetDocumentElements: IXMLDocumentElements;
function GetHasInterfaces: Boolean;
function GetInterfaces: IXMLInterfaces;
property HasEnumerations: Boolean read GetHasEnumerations; property HasEnumerations: Boolean read GetHasEnumerations;
property Enumerations: IXMLEnumerations read GetEnumerations; property Enumerations: IXMLEnumerations read GetEnumerations;
property HasDocumentElements: Boolean read GetHasDocumentElements; property HasDocumentElements: Boolean read GetHasDocumentElements;
property DocumentElements: IXMLDocumentElements read GetDocumentElements; property DocumentElements: IXMLDocumentElements read GetDocumentElements;
property HasInterfaces: Boolean read GetHasInterfaces;
property Interfaces: IXMLInterfaces read GetInterfaces;
end; end;
IXMLEnumerations = interface(IXMLNodeCollection) IXMLEnumerations = interface(IXMLNodeCollection)
['{BD382537-6E8E-4821-A6FB-598234A7B646}'] ['{1D5E90E0-06DD-4476-BA73-0753D35B6193}']
function Get_Enumeration(Index: Integer): IXMLEnumeration; function Get_Enumeration(Index: Integer): IXMLEnumeration;
function Add: IXMLEnumeration; function Add: IXMLEnumeration;
function Insert(Index: Integer): IXMLEnumeration; function Insert(Index: Integer): IXMLEnumeration;
@ -48,22 +54,25 @@ type
end; end;
IXMLEnumeration = interface(IXMLNodeCollection) IXMLEnumeration = interface(IXMLNodeCollection)
['{DC00C775-25B9-4612-A712-9D2DAC346415}'] ['{07097378-D346-4809-B0A2-86C4BA09C124}']
function Get_Member(Index: Integer): IXMLMember; function Get_Member(Index: Integer): IXMLMember;
function Add: IXMLMember; function Add: IXMLMember;
function Insert(Index: Integer): IXMLMember; function Insert(Index: Integer): IXMLMember;
property Member[Index: Integer]: IXMLMember read Get_Member; default; property Member[Index: Integer]: IXMLMember read Get_Member; default;
function GetName: WideString; function GetSchema: WideString;
function GetXPath: WideString;
procedure SetName(const Value: WideString); procedure SetSchema(const Value: WideString);
procedure SetXPath(const Value: WideString);
property Name: WideString read GetName write SetName; property Schema: WideString read GetSchema write SetSchema;
property XPath: WideString read GetXPath write SetXPath;
end; end;
IXMLMember = interface(IXMLNode) IXMLMember = interface(IXMLNode)
['{C242311F-B6B6-44B6-BAF2-40EBE6501963}'] ['{A5C711D5-FEC5-4490-A36B-A2687AB39748}']
function GetName: WideString; function GetName: WideString;
procedure SetName(const Value: WideString); procedure SetName(const Value: WideString);
@ -76,7 +85,7 @@ type
a Document Element. a Document Element.
} }
IXMLDocumentElements = interface(IXMLNodeCollection) IXMLDocumentElements = interface(IXMLNodeCollection)
['{A2036427-9FCE-41DF-B254-4BFBA42258AA}'] ['{E6C9CBB2-7457-4597-939D-AAE9B1C5F42B}']
function Get_DocumentElement(Index: Integer): IXMLDocumentElement; function Get_DocumentElement(Index: Integer): IXMLDocumentElement;
function Add: IXMLDocumentElement; function Add: IXMLDocumentElement;
function Insert(Index: Integer): IXMLDocumentElement; function Insert(Index: Integer): IXMLDocumentElement;
@ -85,12 +94,38 @@ type
end; end;
IXMLDocumentElement = interface(IXMLNode) IXMLDocumentElement = interface(IXMLNode)
['{DBC9940F-A0A3-42A4-83CF-AD90BD0892E5}'] ['{93F6182F-4E03-420A-8E84-49F33DC29FA3}']
function GetName: WideString; function GetSchema: WideString;
function GetXPath: WideString;
procedure SetName(const Value: WideString); procedure SetSchema(const Value: WideString);
procedure SetXPath(const Value: WideString);
property Name: WideString read GetName write SetName; property Schema: WideString read GetSchema write SetSchema;
property XPath: WideString read GetXPath write SetXPath;
end;
IXMLInterfaces = interface(IXMLNodeCollection)
['{A18D3AFF-24FC-45FD-9583-15D9292249D2}']
function Get_InterfaceName(Index: Integer): IXMLInterfaceName;
function Add: IXMLInterfaceName;
function Insert(Index: Integer): IXMLInterfaceName;
property InterfaceName[Index: Integer]: IXMLInterfaceName read Get_InterfaceName; default;
end;
IXMLInterfaceName = interface(IXMLNode)
['{EB24ED8F-0D81-48D5-A420-438CAE003A23}']
function GetHasSchema: Boolean;
function GetSchema: WideString;
function GetXPath: WideString;
procedure SetSchema(const Value: WideString);
procedure SetXPath(const Value: WideString);
property HasSchema: Boolean read GetHasSchema;
property Schema: WideString read GetSchema write SetSchema;
property XPath: WideString read GetXPath write SetXPath;
end; end;
@ -103,6 +138,8 @@ type
function GetEnumerations: IXMLEnumerations; function GetEnumerations: IXMLEnumerations;
function GetHasDocumentElements: Boolean; function GetHasDocumentElements: Boolean;
function GetDocumentElements: IXMLDocumentElements; function GetDocumentElements: IXMLDocumentElements;
function GetHasInterfaces: Boolean;
function GetInterfaces: IXMLInterfaces;
end; end;
TXMLEnumerations = class(TXMLNodeCollection, IXMLEnumerations) TXMLEnumerations = class(TXMLNodeCollection, IXMLEnumerations)
@ -122,9 +159,11 @@ type
function Add: IXMLMember; function Add: IXMLMember;
function Insert(Index: Integer): IXMLMember; function Insert(Index: Integer): IXMLMember;
function GetName: WideString; function GetSchema: WideString;
function GetXPath: WideString;
procedure SetName(const Value: WideString); procedure SetSchema(const Value: WideString);
procedure SetXPath(const Value: WideString);
end; end;
TXMLMember = class(TXMLNode, IXMLMember) TXMLMember = class(TXMLNode, IXMLMember)
@ -145,9 +184,30 @@ type
TXMLDocumentElement = class(TXMLNode, IXMLDocumentElement) TXMLDocumentElement = class(TXMLNode, IXMLDocumentElement)
protected protected
function GetName: WideString; function GetSchema: WideString;
function GetXPath: WideString;
procedure SetName(const Value: WideString); procedure SetSchema(const Value: WideString);
procedure SetXPath(const Value: WideString);
end;
TXMLInterfaces = class(TXMLNodeCollection, IXMLInterfaces)
public
procedure AfterConstruction; override;
protected
function Get_InterfaceName(Index: Integer): IXMLInterfaceName;
function Add: IXMLInterfaceName;
function Insert(Index: Integer): IXMLInterfaceName;
end;
TXMLInterfaceName = class(TXMLNode, IXMLInterfaceName)
protected
function GetHasSchema: Boolean;
function GetSchema: WideString;
function GetXPath: WideString;
procedure SetSchema(const Value: WideString);
procedure SetXPath(const Value: WideString);
end; end;
@ -199,6 +259,7 @@ procedure TXMLDataBindingHints.AfterConstruction;
begin begin
RegisterChildNode('Enumerations', TXMLEnumerations); RegisterChildNode('Enumerations', TXMLEnumerations);
RegisterChildNode('DocumentElements', TXMLDocumentElements); RegisterChildNode('DocumentElements', TXMLDocumentElements);
RegisterChildNode('Interfaces', TXMLInterfaces);
inherited; inherited;
end; end;
@ -224,6 +285,17 @@ begin
Result := (ChildNodes['DocumentElements'] as IXMLDocumentElements); Result := (ChildNodes['DocumentElements'] as IXMLDocumentElements);
end; end;
function TXMLDataBindingHints.GetHasInterfaces: Boolean;
begin
Result := Assigned(ChildNodes.FindNode('Interfaces'));
end;
function TXMLDataBindingHints.GetInterfaces: IXMLInterfaces;
begin
Result := (ChildNodes['Interfaces'] as IXMLInterfaces);
end;
procedure TXMLEnumerations.AfterConstruction; procedure TXMLEnumerations.AfterConstruction;
begin begin
RegisterChildNode('Enumeration', TXMLEnumeration); RegisterChildNode('Enumeration', TXMLEnumeration);
@ -274,14 +346,24 @@ begin
Result := (AddItem(Index) as IXMLMember); Result := (AddItem(Index) as IXMLMember);
end; end;
function TXMLEnumeration.GetName: WideString; function TXMLEnumeration.GetSchema: WideString;
begin begin
Result := AttributeNodes['Name'].Text; Result := AttributeNodes['Schema'].Text;
end; end;
procedure TXMLEnumeration.SetName(const Value: WideString); function TXMLEnumeration.GetXPath: WideString;
begin begin
SetAttribute('Name', Value); Result := AttributeNodes['XPath'].Text;
end;
procedure TXMLEnumeration.SetSchema(const Value: WideString);
begin
SetAttribute('Schema', Value);
end;
procedure TXMLEnumeration.SetXPath(const Value: WideString);
begin
SetAttribute('XPath', Value);
end; end;
function TXMLMember.GetName: WideString; function TXMLMember.GetName: WideString;
@ -319,14 +401,75 @@ begin
Result := (AddItem(Index) as IXMLDocumentElement); Result := (AddItem(Index) as IXMLDocumentElement);
end; end;
function TXMLDocumentElement.GetName: WideString; function TXMLDocumentElement.GetSchema: WideString;
begin begin
Result := AttributeNodes['Name'].Text; Result := AttributeNodes['Schema'].Text;
end; end;
procedure TXMLDocumentElement.SetName(const Value: WideString); function TXMLDocumentElement.GetXPath: WideString;
begin begin
SetAttribute('Name', Value); Result := AttributeNodes['XPath'].Text;
end;
procedure TXMLDocumentElement.SetSchema(const Value: WideString);
begin
SetAttribute('Schema', Value);
end;
procedure TXMLDocumentElement.SetXPath(const Value: WideString);
begin
SetAttribute('XPath', Value);
end;
procedure TXMLInterfaces.AfterConstruction;
begin
RegisterChildNode('InterfaceName', TXMLInterfaceName);
ItemTag := 'InterfaceName';
ItemInterface := IXMLInterfaceName;
inherited;
end;
function TXMLInterfaces.Get_InterfaceName(Index: Integer): IXMLInterfaceName;
begin
Result := (List[Index] as IXMLInterfaceName);
end;
function TXMLInterfaces.Add: IXMLInterfaceName;
begin
Result := (AddItem(-1) as IXMLInterfaceName);
end;
function TXMLInterfaces.Insert(Index: Integer): IXMLInterfaceName;
begin
Result := (AddItem(Index) as IXMLInterfaceName);
end;
function TXMLInterfaceName.GetHasSchema: Boolean;
begin
Result := Assigned(ChildNodes.FindNode('Schema'));
end;
function TXMLInterfaceName.GetSchema: WideString;
begin
Result := AttributeNodes['Schema'].Text;
end;
function TXMLInterfaceName.GetXPath: WideString;
begin
Result := AttributeNodes['XPath'].Text;
end;
procedure TXMLInterfaceName.SetSchema(const Value: WideString);
begin
SetAttribute('Schema', Value);
end;
procedure TXMLInterfaceName.SetXPath(const Value: WideString);
begin
SetAttribute('XPath', Value);
end; end;

View File

@ -24,7 +24,7 @@ type
TXMLDataBindingItemType = (itInterface, itEnumeration, itEnumerationMember, TXMLDataBindingItemType = (itInterface, itEnumeration, itEnumerationMember,
itProperty, itUnresolved, itProperty, itUnresolved,
itComplexTypeAlias, itSimpleTypeAlias); itComplexTypeAlias, itSimpleTypeAlias);
TXMLDataBindingInterfaceType = (ifElement, ifComplexType); TXMLDataBindingInterfaceType = (ifElement, ifComplexType, ifEnumeration);
TXMLDataBindingPropertyType = (ptSimple, ptItem); TXMLDataBindingPropertyType = (ptSimple, ptItem);
TXMLDataBindingOccurance = (boMinOccurs, boMaxOccurs); TXMLDataBindingOccurance = (boMinOccurs, boMaxOccurs);
@ -54,6 +54,7 @@ type
procedure GenerateSchemaObjects(ASchema: TXMLDataBindingSchema; ARootDocument: Boolean); procedure GenerateSchemaObjects(ASchema: TXMLDataBindingSchema; ARootDocument: Boolean);
procedure GenerateElementObjects(ASchema: TXMLDataBindingSchema; ARootDocument: Boolean); procedure GenerateElementObjects(ASchema: TXMLDataBindingSchema; ARootDocument: Boolean);
procedure GenerateComplexTypeObjects(ASchema: TXMLDataBindingSchema); procedure GenerateComplexTypeObjects(ASchema: TXMLDataBindingSchema);
procedure GenerateSimpleTypeObjects(ASchema: TXMLDataBindingSchema);
function CheckElementOccurance(AElement: IXMLElementDef; AOccurance: TXMLDataBindingOccurance): Boolean; function CheckElementOccurance(AElement: IXMLElementDef; AOccurance: TXMLDataBindingOccurance): Boolean;
function IsElementOptional(AElement: IXMLElementDef): Boolean; function IsElementOptional(AElement: IXMLElementDef): Boolean;
@ -88,8 +89,6 @@ type
property SourceFileName: String read FSourceFileName write FSourceFileName; property SourceFileName: String read FSourceFileName write FSourceFileName;
property SchemaCount: Integer read GetSchemaCount; property SchemaCount: Integer read GetSchemaCount;
property Schemas[Index: Integer]: TXMLDataBindingSchema read GetSchemas; property Schemas[Index: Integer]: TXMLDataBindingSchema read GetSchemas;
protected
procedure DoPostProcessItem(AItem: TXMLDataBindingItem);
public public
constructor Create(); constructor Create();
destructor Destroy(); override; destructor Destroy(); override;
@ -234,7 +233,6 @@ type
TXMLDataBindingEnumeration = class(TXMLDataBindingItem) TXMLDataBindingEnumeration = class(TXMLDataBindingItem)
private private
FDataType: IXMLTypeDef;
FMembers: TObjectList; FMembers: TObjectList;
function GetMemberCount(): Integer; function GetMemberCount(): Integer;
@ -242,10 +240,9 @@ type
protected protected
function GetItemType(): TXMLDataBindingItemType; override; function GetItemType(): TXMLDataBindingItemType; override;
public public
constructor Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; ADataType: IXMLTypeDef; const AName: String); constructor Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; AEnumerations: IXMLEnumerationCollection; const AName: String);
destructor Destroy(); override; destructor Destroy(); override;
property DataType: IXMLTypeDef read FDataType;
property MemberCount: Integer read GetMemberCount; property MemberCount: Integer read GetMemberCount;
property Members[Index: Integer]: TXMLDataBindingEnumerationMember read GetMembers; property Members[Index: Integer]: TXMLDataBindingEnumerationMember read GetMembers;
end; end;
@ -574,9 +571,9 @@ begin
for includeIndex := 0 to Pred(ASchema.IncludeCount) do for includeIndex := 0 to Pred(ASchema.IncludeCount) do
GenerateSchemaObjects(ASchema.Includes[includeIndex], False); GenerateSchemaObjects(ASchema.Includes[includeIndex], False);
GenerateElementObjects(ASchema, ARootDocument); GenerateElementObjects(ASchema, ARootDocument);
GenerateComplexTypeObjects(ASchema); GenerateComplexTypeObjects(ASchema);
GenerateSimpleTypeObjects(ASchema);
end; end;
@ -627,6 +624,29 @@ begin
end; end;
procedure TXMLDataBindingGenerator.GenerateSimpleTypeObjects(ASchema: TXMLDataBindingSchema);
var
schemaDef: IXMLSchemaDef;
simpleTypeIndex: Integer;
simpleType: IXMLSimpleTypeDef;
enumerationObject: TXMLDataBindingEnumeration;
begin
schemaDef := ASchema.SchemaDef;
for simpleTypeIndex := 0 to Pred(schemaDef.SimpleTypes.Count) do
begin
simpleType := schemaDef.SimpleTypes[simpleTypeIndex];
if simpleType.Enumerations.Count > 0 then
begin
enumerationObject := TXMLDataBindingEnumeration.Create(Self, simpleType, simpleType.Enumerations, simpleType.Name);
ASchema.AddItem(enumerationObject);
end;
end;
end;
function TXMLDataBindingGenerator.CheckElementOccurance(AElement: IXMLElementDef; AOccurance: TXMLDataBindingOccurance): Boolean; function TXMLDataBindingGenerator.CheckElementOccurance(AElement: IXMLElementDef; AOccurance: TXMLDataBindingOccurance): Boolean;
function CheckParent(const ANode: IXMLNode): Boolean; function CheckParent(const ANode: IXMLNode): Boolean;
@ -719,7 +739,7 @@ begin
if AElement.DataType.IsComplex then if AElement.DataType.IsComplex then
begin begin
{ Find data type. If not found, mark as "resolve later". } { Find data type. If not found, mark as "resolve later". }
Result := FindInterface(ASchema, AElement.DataTypeName, ifComplexType); Result := FindInterface(ASchema, AElement.DataTypeName, ifComplexType);
if not Assigned(Result) then if not Assigned(Result) then
begin begin
@ -735,6 +755,16 @@ begin
complexAliasItem.Item := Result; complexAliasItem.Item := Result;
ASchema.AddItem(complexAliasItem); ASchema.AddItem(complexAliasItem);
end; end;
end else if AElement.DataType.Enumerations.Count > 0 then
begin
{ References enumeration. }
Result := FindEnumeration(ASchema, AElement.DataTypeName);
if not Assigned(Result) then
begin
Result := TXMLDataBindingUnresolvedItem.Create(Self, AElement, AElement.DataTypeName, ifEnumeration);
ASchema.AddItem(Result);
end;
end else if AElement.IsGlobal then end else if AElement.IsGlobal then
begin begin
{ The element is global, but only references a simple type. } { The element is global, but only references a simple type. }
@ -751,7 +781,7 @@ begin
if AElement.DataType.Enumerations.Count > 0 then if AElement.DataType.Enumerations.Count > 0 then
begin begin
{ Enumeration } { Enumeration }
enumerationObject := TXMLDataBindingEnumeration.Create(Self, AElement, AElement.DataType, AElement.Name); enumerationObject := TXMLDataBindingEnumeration.Create(Self, AElement, AElement.DataType.Enumerations, AElement.Name);
ASchema.AddItem(enumerationObject); ASchema.AddItem(enumerationObject);
Result := enumerationObject; Result := enumerationObject;
end else if AElement.DataType.IsComplex then end else if AElement.DataType.IsComplex then
@ -1009,11 +1039,16 @@ begin
if not Assigned(AItem) then if not Assigned(AItem) then
Exit; Exit;
referenceItem := FindInterface(ASchema, AItem.Name, AItem.InterfaceType); if AItem.InterfaceType = ifEnumeration then
referenceItem := FindEnumeration(ASchema, AItem.Name)
else
begin
referenceItem := FindInterface(ASchema, AItem.Name, AItem.InterfaceType);
if (not Assigned(referenceItem)) and if (not Assigned(referenceItem)) and
(AItem.InterfaceType = ifElement) then (AItem.InterfaceType = ifElement) then
referenceItem := FindEnumeration(ASchema, AItem.Name); referenceItem := FindEnumeration(ASchema, AItem.Name);
end;
if Assigned(referenceItem) then if Assigned(referenceItem) then
ReplaceItem(AItem, referenceItem); ReplaceItem(AItem, referenceItem);
@ -1172,8 +1207,7 @@ var
begin begin
{ Translate name } { Translate name }
AItem.TranslatedName := TranslateItemName(AItem); AItem.TranslatedName := TranslateItemName(AItem);
DoPostProcessItem(AItem);
{ Extract collections } { Extract collections }
if AItem.ItemType = itInterface then if AItem.ItemType = itInterface then
@ -1263,13 +1297,6 @@ begin
end; end;
procedure TXMLDataBindingGenerator.DoPostProcessItem(AItem: TXMLDataBindingItem);
begin
if Assigned(FOnPostProcessItem) then
FOnPostProcessItem(Self, AItem);
end;
{ TXMLDataBindingGeneratorItem } { TXMLDataBindingGeneratorItem }
constructor TXMLDataBindingGeneratorItem.Create(AOwner: TXMLDataBindingGenerator); constructor TXMLDataBindingGeneratorItem.Create(AOwner: TXMLDataBindingGenerator);
begin begin
@ -1528,18 +1555,17 @@ end;
{ TXMLDataBindingEnumeration } { TXMLDataBindingEnumeration }
constructor TXMLDataBindingEnumeration.Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; ADataType: IXMLTypeDef; const AName: String); constructor TXMLDataBindingEnumeration.Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; AEnumerations: IXMLEnumerationCollection; const AName: String);
var var
memberIndex: Integer; memberIndex: Integer;
begin begin
inherited Create(AOwner, ASchemaItem, AName); inherited Create(AOwner, ASchemaItem, AName);
FDataType := ADataType;
FMembers := TObjectList.Create(); FMembers := TObjectList.Create();
for memberIndex := 0 to Pred(ADataType.Enumerations.Count) do for memberIndex := 0 to Pred(AEnumerations.Count) do
FMembers.Add(TXMLDataBindingEnumerationMember.Create(Owner, Self, ADataType.Enumerations.Items[memberIndex].Value)); FMembers.Add(TXMLDataBindingEnumerationMember.Create(Owner, Self, AEnumerations.Items[memberIndex].Value));
end; end;

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.x2software.net/xsd/databinding/DataBindingHints.xsd" xmlns:tns="http://www.x2software.net/xsd/databinding/DataBindingHints.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:schema targetNamespace="http://www.x2software.net/xsd/databinding/DataBindingHints.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.x2software.net/xsd/databinding/DataBindingHints.xsd" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="DataBindingHints"> <xs:element name="DataBindingHints">
<xs:annotation> <xs:annotation>
<xs:documentation>Contains hints and mappings for the data binding output</xs:documentation> <xs:documentation>Contains hints and mappings for the data binding output</xs:documentation>
@ -22,7 +22,8 @@
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
</xs:sequence> </xs:sequence>
<xs:attribute name="Name" type="xs:string" use="required"/> <xs:attribute name="Schema" type="xs:string" use="required"/>
<xs:attribute name="XPath" type="xs:string" use="required"/>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
</xs:sequence> </xs:sequence>
@ -36,7 +37,24 @@
<xs:sequence> <xs:sequence>
<xs:element name="DocumentElement" minOccurs="0" maxOccurs="unbounded"> <xs:element name="DocumentElement" minOccurs="0" maxOccurs="unbounded">
<xs:complexType> <xs:complexType>
<xs:attribute name="Name" type="xs:string" use="required"/> <xs:attribute name="Schema" type="xs:string" use="required"/>
<xs:attribute name="XPath" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Interfaces" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="InterfaceName" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Schema" type="xs:string" use="optional"/>
<xs:attribute name="XPath" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
</xs:sequence> </xs:sequence>