diff --git a/Forms/MainFrm.pas b/Forms/MainFrm.pas index 41d9969..17a0394 100644 --- a/Forms/MainFrm.pas +++ b/Forms/MainFrm.pas @@ -92,10 +92,15 @@ uses const - XPathHintEnumerationMember = '/d:DataBindingHints/d:Enumerations' + + XPathHintBase = '/d:DataBindingHints'; + + XPathHintEnumerationMember = XPathHintBase + '/d:Enumerations' + '/d:Enumeration[@Name=''%:s'']' + '/d:Member[@Name=''%:s'']/text()'; + XPathHintDocumentElement = XPathHintBase + '/d:DocumentElements' + + '/d:DocumentElement[@Name=''%:s'']'; + {$R *.dfm} @@ -212,6 +217,14 @@ begin 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; diff --git a/Units/DataBindingHintsXML.pas b/Units/DataBindingHintsXML.pas index 4bbc815..376de3c 100644 --- a/Units/DataBindingHintsXML.pas +++ b/Units/DataBindingHintsXML.pas @@ -1,7 +1,7 @@ { X2Software XML Data Binding - Generated on: 24-4-2008 11:37:14 + Generated on: 25-4-2008 10:37:37 Generated from: P:\test\XMLDataBinding\XSD\DataBindingHints.xsd } unit DataBindingHintsXML; @@ -18,22 +18,28 @@ type IXMLEnumerations = interface; IXMLEnumeration = interface; IXMLMember = interface; + IXMLDocumentElements = interface; + IXMLDocumentElement = interface; { Interfaces for DataBindingHints } { Contains hints and mappings for the data binding output } IXMLDataBindingHints = interface(IXMLNode) - ['{BF3AC439-748A-4051-B05D-31067CDF0781}'] + ['{33A3ED30-3F1C-4607-A848-D3F17297687F}'] function GetHasEnumerations: Boolean; function GetEnumerations: IXMLEnumerations; + function GetHasDocumentElements: Boolean; + function GetDocumentElements: IXMLDocumentElements; property HasEnumerations: Boolean read GetHasEnumerations; property Enumerations: IXMLEnumerations read GetEnumerations; + property HasDocumentElements: Boolean read GetHasDocumentElements; + property DocumentElements: IXMLDocumentElements read GetDocumentElements; end; IXMLEnumerations = interface(IXMLNodeCollection) - ['{12A3082B-138D-4F00-8D53-AEE76E4A9AD9}'] + ['{BD382537-6E8E-4821-A6FB-598234A7B646}'] function Get_Enumeration(Index: Integer): IXMLEnumeration; function Add: IXMLEnumeration; function Insert(Index: Integer): IXMLEnumeration; @@ -42,7 +48,7 @@ type end; IXMLEnumeration = interface(IXMLNodeCollection) - ['{BAF25450-A88E-42A7-A466-652E5EA90D1F}'] + ['{DC00C775-25B9-4612-A712-9D2DAC346415}'] function Get_Member(Index: Integer): IXMLMember; function Add: IXMLMember; function Insert(Index: Integer): IXMLMember; @@ -57,7 +63,29 @@ type end; IXMLMember = interface(IXMLNode) - ['{202F3AB6-9908-4B87-9271-16B737BFC7CB}'] + ['{C242311F-B6B6-44B6-BAF2-40EBE6501963}'] + function GetName: WideString; + + procedure SetName(const Value: WideString); + + property Name: WideString read GetName write SetName; + end; + + { + If present, only elements which are included in this list will be marked as + a Document Element. + } + IXMLDocumentElements = interface(IXMLNodeCollection) + ['{A2036427-9FCE-41DF-B254-4BFBA42258AA}'] + function Get_DocumentElement(Index: Integer): IXMLDocumentElement; + function Add: IXMLDocumentElement; + function Insert(Index: Integer): IXMLDocumentElement; + + property DocumentElement[Index: Integer]: IXMLDocumentElement read Get_DocumentElement; default; + end; + + IXMLDocumentElement = interface(IXMLNode) + ['{DBC9940F-A0A3-42A4-83CF-AD90BD0892E5}'] function GetName: WideString; procedure SetName(const Value: WideString); @@ -73,6 +101,8 @@ type protected function GetHasEnumerations: Boolean; function GetEnumerations: IXMLEnumerations; + function GetHasDocumentElements: Boolean; + function GetDocumentElements: IXMLDocumentElements; end; TXMLEnumerations = class(TXMLNodeCollection, IXMLEnumerations) @@ -104,6 +134,22 @@ type procedure SetName(const Value: WideString); end; + TXMLDocumentElements = class(TXMLNodeCollection, IXMLDocumentElements) + public + procedure AfterConstruction; override; + protected + function Get_DocumentElement(Index: Integer): IXMLDocumentElement; + function Add: IXMLDocumentElement; + function Insert(Index: Integer): IXMLDocumentElement; + end; + + TXMLDocumentElement = class(TXMLNode, IXMLDocumentElement) + protected + function GetName: WideString; + + procedure SetName(const Value: WideString); + end; + { Document functions } function GetDataBindingHints(ADocument: IXMLDocument): IXMLDataBindingHints; @@ -152,6 +198,7 @@ end; procedure TXMLDataBindingHints.AfterConstruction; begin RegisterChildNode('Enumerations', TXMLEnumerations); + RegisterChildNode('DocumentElements', TXMLDocumentElements); inherited; end; @@ -166,6 +213,17 @@ begin Result := (ChildNodes['Enumerations'] as IXMLEnumerations); end; +function TXMLDataBindingHints.GetHasDocumentElements: Boolean; +begin + Result := Assigned(ChildNodes.FindNode('DocumentElements')); +end; + + +function TXMLDataBindingHints.GetDocumentElements: IXMLDocumentElements; +begin + Result := (ChildNodes['DocumentElements'] as IXMLDocumentElements); +end; + procedure TXMLEnumerations.AfterConstruction; begin RegisterChildNode('Enumeration', TXMLEnumeration); @@ -236,6 +294,41 @@ begin SetAttribute('Name', Value); end; +procedure TXMLDocumentElements.AfterConstruction; +begin + RegisterChildNode('DocumentElement', TXMLDocumentElement); + + ItemTag := 'DocumentElement'; + ItemInterface := IXMLDocumentElement; + + inherited; +end; + +function TXMLDocumentElements.Get_DocumentElement(Index: Integer): IXMLDocumentElement; +begin + Result := (List[Index] as IXMLDocumentElement); +end; + +function TXMLDocumentElements.Add: IXMLDocumentElement; +begin + Result := (AddItem(-1) as IXMLDocumentElement); +end; + +function TXMLDocumentElements.Insert(Index: Integer): IXMLDocumentElement; +begin + Result := (AddItem(Index) as IXMLDocumentElement); +end; + +function TXMLDocumentElement.GetName: WideString; +begin + Result := AttributeNodes['Name'].Text; +end; + +procedure TXMLDocumentElement.SetName(const Value: WideString); +begin + SetAttribute('Name', Value); +end; + end. diff --git a/Units/DelphiXMLDataBindingGenerator.pas b/Units/DelphiXMLDataBindingGenerator.pas index 4a9ccd2..cdda3ba 100644 --- a/Units/DelphiXMLDataBindingGenerator.pas +++ b/Units/DelphiXMLDataBindingGenerator.pas @@ -1089,7 +1089,6 @@ begin { If the property has a collection, it's Count property will be enough to check if an item is present, no need to write a HasX method. } - // #ToDo3 (MvR) 14-4-2008: move first check to XMLDataBindingGenerator ? writeOptional := False; writeNil := AProperty.IsNillable; diff --git a/Units/XMLDataBindingGenerator.pas b/Units/XMLDataBindingGenerator.pas index ee24e30..65b8187 100644 --- a/Units/XMLDataBindingGenerator.pas +++ b/Units/XMLDataBindingGenerator.pas @@ -1,5 +1,7 @@ unit XMLDataBindingGenerator; +// #ToDo2 (MvR) 25-4-2008: typed wrapper for NodeValue if needed (eg. element with attributes and a value) + interface uses Classes, @@ -527,8 +529,6 @@ var 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]); @@ -1189,13 +1189,15 @@ begin if repeatingItems.Count > 0 then begin - if repeatingItems.Count = 1 then + if (repeatingItems.Count = 1) and + (not Assigned(interfaceItem.BaseItem)) then begin { Single repeating child, the item itself is a collection parent } interfaceItem.CollectionItem := TXMLDataBindingProperty(repeatingItems[0]); end else begin - { Multiple repeating children, create intermediate collections for each } + { Multiple repeating children or this interface is a descendant, + create intermediate collections for each } for propertyIndex := 0 to Pred(repeatingItems.Count) do begin propertyItem := TXMLDataBindingProperty(repeatingItems[propertyIndex]); @@ -1204,8 +1206,6 @@ begin // exists in the schema, as it could cause // conflicts. - // #ToDo1 (MvR) 7-4-2008: check if the interfaceItem has a BaseItem, - // can't be combined with being a collection case propertyItem.PropertyType of ptSimple: collectionName := propertyItem.TranslatedName + CollectionPostfix; ptItem: collectionName := propertyItem.TranslatedName + CollectionPostfix; diff --git a/XSD/DataBindingHints.xsd b/XSD/DataBindingHints.xsd index a407db9..446482b 100644 --- a/XSD/DataBindingHints.xsd +++ b/XSD/DataBindingHints.xsd @@ -1,11 +1,11 @@ - + Contains hints and mappings for the data binding output - + @@ -28,7 +28,21 @@ - + + + If present, only elements which are included in this list will be marked as a Document Element. + + + + + + + + + + + +