From dba905ace407db7a8d42a90ad6826d0810e54809 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Mon, 31 Mar 2008 21:15:13 +0000 Subject: [PATCH] Fixed: support for global elements of a complex type --- Units/DelphiXMLDataBindingGenerator.pas | 6 +- Units/XMLDataBindingGenerator.pas | 151 ++++++++++++++++++++---- X2XMLDataBindingCmdLine.bdsproj | 2 +- X2XMLDataBindingCmdLine.cfg | 6 +- 4 files changed, 136 insertions(+), 29 deletions(-) diff --git a/Units/DelphiXMLDataBindingGenerator.pas b/Units/DelphiXMLDataBindingGenerator.pas index bf3bc3b..a8bf6b9 100644 --- a/Units/DelphiXMLDataBindingGenerator.pas +++ b/Units/DelphiXMLDataBindingGenerator.pas @@ -783,8 +783,8 @@ begin end; ptItem: begin - dataTypeName := PrefixInterface + AItem.CollectionItem.TranslatedName; - dataClassName := PrefixClass + AItem.CollectionItem.TranslatedName; + dataTypeName := PrefixInterface + AItem.CollectionItemTranslatedName; + dataClassName := PrefixClass + AItem.CollectionItemTranslatedName; dataIntfName := dataTypeName; end; end; @@ -886,7 +886,7 @@ begin end; AStream.Write(sourceCode.Format(['Name', AItem.TranslatedName, - 'ItemName', AItem.CollectionItem.TranslatedName, + 'ItemName', AItem.CollectionItemTranslatedName, 'ItemSourceName', AItem.CollectionItem.Name, 'DataType', dataTypeName, 'DataClass', dataClassName, diff --git a/Units/XMLDataBindingGenerator.pas b/Units/XMLDataBindingGenerator.pas index fcfdcb5..5acac3c 100644 --- a/Units/XMLDataBindingGenerator.pas +++ b/Units/XMLDataBindingGenerator.pas @@ -21,7 +21,8 @@ type TXMLDataBindingOutputType = (otSingle, otMultiple); TXMLDataBindingItemType = (itInterface, itCollection, itEnumeration, - itEnumerationMember, itProperty, itForward); + itEnumerationMember, itProperty, itForward, + itComplexTypeElement); TXMLDataBindingInterfaceType = (ifElement, ifComplexType); TXMLDataBindingPropertyType = (ptSimple, ptItem); @@ -37,6 +38,7 @@ type FSourceFileName: String; FSchemas: TObjectList; + FMustResolve: Boolean; function GetSchemaCount(): Integer; function GetSchemas(Index: Integer): TXMLDataBindingSchema; @@ -179,11 +181,16 @@ type private FCollectionItem: TXMLDataBindingProperty; + function GetActualCollectionItem(): TXMLDataBindingItem; + function GetCollectionItemName(): String; + function GetCollectionItemTranslatedName(): String; procedure SetCollectionItem(const Value: TXMLDataBindingProperty); protected function GetItemType(): TXMLDataBindingItemType; override; public - property CollectionItem: TXMLDataBindingProperty read FCollectionItem; + property CollectionItem: TXMLDataBindingProperty read FCollectionItem; + property CollectionItemName: String read GetCollectionItemName; + property CollectionItemTranslatedName: String read GetCollectionItemTranslatedName; end; @@ -275,12 +282,23 @@ type end; + TXMLDataBindingComplexTypeElementItem = class(TXMLDataBindingItem) + private + FItem: TXMLDataBindingItem; + protected + function GetItemType(): TXMLDataBindingItemType; override; + public + property Item: TXMLDataBindingItem read FItem write FItem; + end; + + implementation uses SysUtils, Windows, XMLDoc, XMLIntf, + XMLSchemaTags, X2UtHashes; @@ -300,6 +318,25 @@ begin end; +function GetActualItem(AItem: TXMLDataBindingItem): TXMLDataBindingItem; +begin + Result := AItem; + + while Assigned(Result) do + begin + case Result.ItemType of + itForward: + Result := TXMLDataBindingForwardItem(Result).Item; + + itComplexTypeElement: + Result := TXMLDataBindingComplexTypeElementItem(Result).Item; + else + break; + end; + end; +end; + + { TXMLDataBindingGenerator } constructor TXMLDataBindingGenerator.Create(); begin @@ -340,11 +377,16 @@ begin GenerateSchemaObjects(Schemas[schemaIndex], (schemaIndex = 0)); - { Process unresolved references } + { Process unresolved references + - some references can't be resolved the first time (especially + ComplexTypeElement references). Fix this workaround some time. } for schemaIndex := 0 to Pred(SchemaCount) do ResolveSchema(Schemas[schemaIndex]); + for schemaIndex := 0 to Pred(SchemaCount) do + ResolveSchema(Schemas[schemaIndex]); + { Collapse collections } @@ -551,6 +593,7 @@ var elementIndex: Integer; enumerationObject: TXMLDataBindingEnumeration; interfaceObject: TXMLDataBindingInterface; + complexTypeElement: TXMLDataBindingComplexTypeElementItem; begin Result := nil; @@ -569,16 +612,25 @@ begin end else begin if (not AElement.DataType.IsAnonymous) and - (AElement.DataType.IsComplex) then + AElement.DataType.IsComplex then begin { 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 begin Result := TXMLDataBindingForwardItem.Create(AElement, AElement.DataTypeName, ifComplexType); ASchema.AddItem(Result); end; + + if AElement.IsGlobal then + begin + { The element is global, but only references a complex type. Keep track + to properly resolve references to the element. } + complexTypeElement := TXMLDataBindingComplexTypeElementItem.Create(AElement, AElement.Name); + complexTypeElement.Item := Result; + ASchema.AddItem(complexTypeElement); + end; end; if not Assigned(Result) then @@ -643,7 +695,7 @@ begin { Create intermediate object for collections } if Assigned(propertyType) then propertyItem := TXMLDataBindingItemProperty.Create(AElement, - AElement.Name, + propertyType.Name, propertyType) else propertyItem := TXMLDataBindingSimpleProperty.Create(AElement, @@ -719,13 +771,23 @@ type procedure TXMLDataBindingGenerator.FindInterfaceProc(AItem: TXMLDataBindingItem; AData: Pointer; var AAbort: Boolean); var - findInfo: PFindInterfaceInfo; + findInfo: PFindInterfaceInfo; begin + AAbort := False; findInfo := PFindInterfaceInfo(AData); - AAbort := (AItem.ItemType = itInterface) and - (TXMLDataBindingInterface(AItem).InterfaceType = findInfo^.InterfaceType) and - (AItem.Name = findInfo^.Name); + + + if AItem.Name = findInfo^.Name then + begin + case AItem.ItemType of + itInterface: + AAbort := (TXMLDataBindingInterface(AItem).InterfaceType = findInfo^.InterfaceType); + + itComplexTypeElement: + AAbort := (findInfo^.InterfaceType = ifElement); + end; + end; end; @@ -736,7 +798,7 @@ var begin findInfo.InterfaceType := AType; findInfo.Name := AName; - Result := TXMLDataBindingInterface(IterateSchemaItems(ASchema, FindInterfaceProc, @findInfo)); + Result := TXMLDataBindingInterface(GetActualItem(IterateSchemaItems(ASchema, FindInterfaceProc, @findInfo))); end; @@ -791,7 +853,8 @@ begin { Resolve base interface } interfaceItem := TXMLDataBindingInterface(item); - if Length(interfaceItem.BaseName) > 0 then + if (not Assigned(interfaceItem.BaseItem)) and + (Length(interfaceItem.BaseName) > 0) then interfaceItem.BaseItem := FindInterface(ASchema, interfaceItem.BaseName, ifComplexType); end; @@ -813,14 +876,17 @@ begin { Resolve forwarded item } forwardItem := TXMLDataBindingForwardItem(AItem); - referenceItem := FindInterface(ASchema, AItem.Name, forwardItem.InterfaceType); + if not Assigned(forwardItem.Item) then + begin + referenceItem := FindInterface(ASchema, AItem.Name, forwardItem.InterfaceType); - if (not Assigned(referenceItem)) and - (forwardItem.InterfaceType = ifElement) then - referenceItem := FindEnumeration(ASchema, AItem.Name); + if (not Assigned(referenceItem)) and + (forwardItem.InterfaceType = ifElement) then + referenceItem := FindEnumeration(ASchema, AItem.Name); - if Assigned(referenceItem) then - forwardItem.Item := referenceItem; + if Assigned(referenceItem) then + forwardItem.Item := referenceItem; + end; end; @@ -1164,6 +1230,43 @@ begin end; +function TXMLDataBindingCollection.GetActualCollectionItem(): TXMLDataBindingItem; +begin + Result := nil; + + if Assigned(CollectionItem) then + begin + case CollectionItem.PropertyType of + ptSimple: Result := CollectionItem; + ptItem: Result := TXMLDataBindingItemProperty(CollectionItem).Item; + end; + end; +end; + +function TXMLDataBindingCollection.GetCollectionItemName(): String; +var + item: TXMLDataBindingItem; + +begin + Result := ''; + item := GetActualCollectionItem(); + if Assigned(item) then + Result := item.Name; +end; + + +function TXMLDataBindingCollection.GetCollectionItemTranslatedName(): String; +var + item: TXMLDataBindingItem; + +begin + Result := ''; + item := GetActualCollectionItem(); + if Assigned(item) then + Result := item.Name; +end; + + procedure TXMLDataBindingCollection.SetCollectionItem(const Value: TXMLDataBindingProperty); begin FCollectionItem := Value; @@ -1278,10 +1381,7 @@ end; function TXMLDataBindingItemProperty.GetItem(): TXMLDataBindingItem; begin - Result := FItem; - - while Assigned(Result) and (Result.ItemType = itForward) do - Result := TXMLDataBindingForwardItem(Result).Item; + Result := GetActualItem(FItem); end; @@ -1299,6 +1399,13 @@ begin Result := itForward; end; + +{ TXMLDataBindingComplexTypeElementItem } +function TXMLDataBindingComplexTypeElementItem.GetItemType(): TXMLDataBindingItemType; +begin + Result := itComplexTypeElement; +end; + end. diff --git a/X2XMLDataBindingCmdLine.bdsproj b/X2XMLDataBindingCmdLine.bdsproj index 034279f..b8a3d43 100644 --- a/X2XMLDataBindingCmdLine.bdsproj +++ b/X2XMLDataBindingCmdLine.bdsproj @@ -130,7 +130,7 @@ False - "F:\XTxXSD\Offerte.xsd" "F:\XTxXSD\Output\xml_Offerte.pas" + "F:\XTxXSD\Ombouw.xsd" "F:\XTxXSD\Output\xml_Offerte.pas" False diff --git a/X2XMLDataBindingCmdLine.cfg b/X2XMLDataBindingCmdLine.cfg index f8bbbd6..8a733fd 100644 --- a/X2XMLDataBindingCmdLine.cfg +++ b/X2XMLDataBindingCmdLine.cfg @@ -32,9 +32,9 @@ -M -$M16384,1048576 -K$00400000 --N"Lib" --LE"c:\program files\borland\delphi7\Projects\Bpl" --LN"c:\program files\borland\delphi7\Projects\Bpl" +-N0"Lib" +-LE"C:\Documents and Settings\PsychoMark\My Documents\Borland Studio Projects\Bpl" +-LN"C:\Documents and Settings\PsychoMark\My Documents\Borland Studio Projects\Bpl" -w-UNSAFE_TYPE -w-UNSAFE_CODE -w-UNSAFE_CAST