Added: support for specifying the document elements in the hints file

This commit is contained in:
Mark van Renswoude 2008-04-25 10:34:16 +00:00
parent 6764684c9e
commit e1d3f533ab
5 changed files with 135 additions and 16 deletions

View File

@ -92,10 +92,15 @@ uses
const const
XPathHintEnumerationMember = '/d:DataBindingHints/d:Enumerations' + XPathHintBase = '/d:DataBindingHints';
XPathHintEnumerationMember = XPathHintBase + '/d:Enumerations' +
'/d:Enumeration[@Name=''%<Enumeration>:s'']' + '/d:Enumeration[@Name=''%<Enumeration>:s'']' +
'/d:Member[@Name=''%<Member>:s'']/text()'; '/d:Member[@Name=''%<Member>:s'']/text()';
XPathHintDocumentElement = XPathHintBase + '/d:DocumentElements' +
'/d:DocumentElement[@Name=''%<Name>:s'']';
{$R *.dfm} {$R *.dfm}
@ -212,6 +217,14 @@ begin
if Assigned(hint) and (Length(hint.nodeValue) > 0) then if Assigned(hint) and (Length(hint.nodeValue) > 0) then
Item.TranslatedName := hint.nodeValue; Item.TranslatedName := hint.nodeValue;
end; end;
if Item.ItemType = itInterface then
begin
if FHints.HasDocumentElements then
Item.DocumentElement := Assigned(FHintsXPath.selectNode(NamedFormat(XPathHintDocumentElement,
['Name', Item.Name])));
end;
end; end;

View File

@ -1,7 +1,7 @@
{ {
X2Software XML Data Binding 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 Generated from: P:\test\XMLDataBinding\XSD\DataBindingHints.xsd
} }
unit DataBindingHintsXML; unit DataBindingHintsXML;
@ -18,22 +18,28 @@ type
IXMLEnumerations = interface; IXMLEnumerations = interface;
IXMLEnumeration = interface; IXMLEnumeration = interface;
IXMLMember = interface; IXMLMember = interface;
IXMLDocumentElements = interface;
IXMLDocumentElement = 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)
['{BF3AC439-748A-4051-B05D-31067CDF0781}'] ['{33A3ED30-3F1C-4607-A848-D3F17297687F}']
function GetHasEnumerations: Boolean; function GetHasEnumerations: Boolean;
function GetEnumerations: IXMLEnumerations; function GetEnumerations: IXMLEnumerations;
function GetHasDocumentElements: Boolean;
function GetDocumentElements: IXMLDocumentElements;
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 DocumentElements: IXMLDocumentElements read GetDocumentElements;
end; end;
IXMLEnumerations = interface(IXMLNodeCollection) IXMLEnumerations = interface(IXMLNodeCollection)
['{12A3082B-138D-4F00-8D53-AEE76E4A9AD9}'] ['{BD382537-6E8E-4821-A6FB-598234A7B646}']
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;
@ -42,7 +48,7 @@ type
end; end;
IXMLEnumeration = interface(IXMLNodeCollection) IXMLEnumeration = interface(IXMLNodeCollection)
['{BAF25450-A88E-42A7-A466-652E5EA90D1F}'] ['{DC00C775-25B9-4612-A712-9D2DAC346415}']
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;
@ -57,7 +63,29 @@ type
end; end;
IXMLMember = interface(IXMLNode) 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; function GetName: WideString;
procedure SetName(const Value: WideString); procedure SetName(const Value: WideString);
@ -73,6 +101,8 @@ type
protected protected
function GetHasEnumerations: Boolean; function GetHasEnumerations: Boolean;
function GetEnumerations: IXMLEnumerations; function GetEnumerations: IXMLEnumerations;
function GetHasDocumentElements: Boolean;
function GetDocumentElements: IXMLDocumentElements;
end; end;
TXMLEnumerations = class(TXMLNodeCollection, IXMLEnumerations) TXMLEnumerations = class(TXMLNodeCollection, IXMLEnumerations)
@ -104,6 +134,22 @@ type
procedure SetName(const Value: WideString); procedure SetName(const Value: WideString);
end; 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 } { Document functions }
function GetDataBindingHints(ADocument: IXMLDocument): IXMLDataBindingHints; function GetDataBindingHints(ADocument: IXMLDocument): IXMLDataBindingHints;
@ -152,6 +198,7 @@ end;
procedure TXMLDataBindingHints.AfterConstruction; procedure TXMLDataBindingHints.AfterConstruction;
begin begin
RegisterChildNode('Enumerations', TXMLEnumerations); RegisterChildNode('Enumerations', TXMLEnumerations);
RegisterChildNode('DocumentElements', TXMLDocumentElements);
inherited; inherited;
end; end;
@ -166,6 +213,17 @@ begin
Result := (ChildNodes['Enumerations'] as IXMLEnumerations); Result := (ChildNodes['Enumerations'] as IXMLEnumerations);
end; 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; procedure TXMLEnumerations.AfterConstruction;
begin begin
RegisterChildNode('Enumeration', TXMLEnumeration); RegisterChildNode('Enumeration', TXMLEnumeration);
@ -236,6 +294,41 @@ begin
SetAttribute('Name', Value); SetAttribute('Name', Value);
end; 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. end.

View File

@ -1089,7 +1089,6 @@ begin
{ If the property has a collection, it's Count property will be enough { 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. } 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; writeOptional := False;
writeNil := AProperty.IsNillable; writeNil := AProperty.IsNillable;

View File

@ -1,5 +1,7 @@
unit XMLDataBindingGenerator; unit XMLDataBindingGenerator;
// #ToDo2 (MvR) 25-4-2008: typed wrapper for NodeValue if needed (eg. element with attributes and a value)
interface interface
uses uses
Classes, Classes,
@ -527,8 +529,6 @@ var
begin begin
Result := nil; Result := nil;
// #ToDo3 (MvR) 31-1-2007: support more locations than just a filename ?
for includeIndex := 0 to Pred(IncludePaths.Count) do for includeIndex := 0 to Pred(IncludePaths.Count) do
begin begin
includePath := IncludeTrailingPathDelimiter(IncludePaths[includeIndex]); includePath := IncludeTrailingPathDelimiter(IncludePaths[includeIndex]);
@ -1189,13 +1189,15 @@ begin
if repeatingItems.Count > 0 then if repeatingItems.Count > 0 then
begin begin
if repeatingItems.Count = 1 then if (repeatingItems.Count = 1) and
(not Assigned(interfaceItem.BaseItem)) then
begin begin
{ Single repeating child, the item itself is a collection parent } { Single repeating child, the item itself is a collection parent }
interfaceItem.CollectionItem := TXMLDataBindingProperty(repeatingItems[0]); interfaceItem.CollectionItem := TXMLDataBindingProperty(repeatingItems[0]);
end else end else
begin 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 for propertyIndex := 0 to Pred(repeatingItems.Count) do
begin begin
propertyItem := TXMLDataBindingProperty(repeatingItems[propertyIndex]); propertyItem := TXMLDataBindingProperty(repeatingItems[propertyIndex]);
@ -1204,8 +1206,6 @@ begin
// exists in the schema, as it could cause // exists in the schema, as it could cause
// conflicts. // 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 case propertyItem.PropertyType of
ptSimple: collectionName := propertyItem.TranslatedName + CollectionPostfix; ptSimple: collectionName := propertyItem.TranslatedName + CollectionPostfix;
ptItem: collectionName := propertyItem.TranslatedName + CollectionPostfix; ptItem: collectionName := propertyItem.TranslatedName + CollectionPostfix;

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:tns="http://www.x2software.net/xsd/databinding/DataBindingHints.xsd" targetNamespace="http://www.x2software.net/xsd/databinding/DataBindingHints.xsd"> <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: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>
</xs:annotation> </xs:annotation>
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:all>
<xs:element name="Enumerations" minOccurs="0"> <xs:element name="Enumerations" minOccurs="0">
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
@ -28,7 +28,21 @@
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
</xs:sequence> <xs:element name="DocumentElements" minOccurs="0">
<xs:annotation>
<xs:documentation>If present, only elements which are included in this list will be marked as a Document Element.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="DocumentElement" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="Name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
</xs:schema> </xs:schema>