Fixed: support for nillable elements

This commit is contained in:
Mark van Renswoude 2008-04-21 15:24:33 +00:00
parent 0d63424104
commit 727a5dca46
3 changed files with 72 additions and 15 deletions

View File

@ -447,11 +447,15 @@ begin
end;
end;
if hasItem and (ASection = dxsInterface) then
if ASection = dxsInterface then
begin
// #ToDo3 (MvR) 9-3-2008: namespace support?
AStream.WriteLn('const');
AStream.WriteLn(' TargetNamespace = '''';');
AStream.WriteLn(' XMLSchemaInstanceURI = ''http://www.w3.org/2001/XMLSchema-instance'';');
if hasItem then
// #ToDo3 (MvR) 9-3-2008: namespace support?
AStream.WriteLn(' TargetNamespace = '''';');
AStream.WriteLn();
AStream.WriteLn();
end;
@ -1063,6 +1067,7 @@ function TDelphiXMLDataBindingGenerator.WriteSchemaInterfaceProperty(AStream: TS
var
sourceCode: TNamedFormatStringList;
writeOptional: Boolean;
writeNil: Boolean;
writeTextProp: Boolean;
propertyItem: TXMLDataBindingItem;
dataTypeName: String;
@ -1075,13 +1080,19 @@ begin
if AProperty = AItem.CollectionItem then
Exit;
{ 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 := not Assigned(AProperty.Collection) and
AProperty.IsOptional and
(AMember in [dxmPropertyGet, dxmPropertyDeclaration]);
writeOptional := False;
writeNil := False;
if AMember in [dxmPropertyGet, dxmPropertyDeclaration] then
begin
writeOptional := not Assigned(AProperty.Collection) and
AProperty.IsOptional;
writeNil := AProperty.IsNillable;
end;
dataTypeName := '';
@ -1139,6 +1150,9 @@ begin
if writeOptional then
sourceCode.Add(PropertyIntfMethodGetOptional);
if writeNil then
sourceCode.Add(PropertyIntfMethodGetNil);
if writeTextProp then
sourceCode.Add(PropertyIntfMethodGetText);
@ -1164,6 +1178,9 @@ begin
if writeOptional then
sourceCode.Add(PropertyInterfaceOptional);
if writeNil then
sourceCode.Add(PropertyInterfaceNil);
if AProperty.IsReadOnly then
begin
if writeTextProp then
@ -1187,10 +1204,14 @@ begin
dxmPropertyGet:
begin
WriteNewLine;
// #ToDo1 (MvR) 21-4-2008: optional attributes!
if writeOptional then
sourceCode.Add(PropertyImplMethodGetOptional);
if writeNil then
sourceCode.Add(PropertyImplMethodGetNil);
if writeTextProp then
sourceCode.Add(PropertyImplMethodGetText);

View File

@ -73,12 +73,14 @@ const
PropertyIntfMethodGetOptional = ' function GetHas%<PropertyName>:s: Boolean;';
PropertyIntfMethodGetNil = ' function GetIs%<PropertyName>:sNil: Boolean;';
PropertyIntfMethodGetText = ' function Get%<PropertyName>:sText: WideString;';
PropertyIntfMethodGet = ' function Get%<PropertyName>:s: %<DataType>:s;';
PropertyIntfMethodSetText = ' procedure Set%<PropertyName>:sText(const Value: WideString);';
PropertyIntfMethodSet = ' procedure Set%<PropertyName>:s(const Value: %<DataType>:s);';
PropertyInterfaceOptional = ' property Has%<PropertyName>:s: Boolean read GetHas%<PropertyName>:s;';
PropertyInterfaceNil = ' property Is%<PropertyName>:sNil: Boolean read GetIs%<PropertyName>:sNil;';
PropertyInterfaceTextReadOnly = ' property %<PropertyName>:sText: WideString read Get%<PropertyName>:sText;';
PropertyInterfaceReadOnly = ' property %<PropertyName>:s: %<DataType>:s read Get%<PropertyName>:s;';
PropertyInterfaceText = ' property %<PropertyName>:sText: WideString read Get%<PropertyName>:sText write Set%<PropertyName>:sText;';
@ -90,6 +92,17 @@ const
'end;' + CrLf +
'' + CrLf;
PropertyImplMethodGetNil = 'function TXML%<Name>:s.GetIs%<PropertyName>:sNil: Boolean;' + CrLf +
'var' + CrLf +
' childNode: IXMLNode;' + CrLf +
'' + CrLf +
'begin' + CrLf +
' childNode := ChildNodes[''%<PropertySourceName>:s''];' + CrLf +
' Result := childNode.HasAttribute(''nil'', XMLSchemaInstanceURI) and' + CrLf +
' StrToBoolDef(childNode.GetAttributeNS(''nil'', XMLSchemaInstanceURI), False);' + CrLf +
'end;' + CrLf +
'' + CrLf;
PropertyImplMethodGetText = 'function TXML%<Name>:s.Get%<PropertyName>:sText: WideString;' + CrLf +
'begin' + CrLf +
' Result := ChildNodes[''%<PropertySourceName>:s''].NodeValue;' + CrLf +

View File

@ -14,6 +14,7 @@ type
TXMLDataBindingEnumerationMember = class;
TXMLDataBindingEnumeration = class;
TXMLDataBindingProperty = class;
TXMLDataBindingItemProperty = class;
TXMLDataBindingUnresolvedItem = class;
@ -243,6 +244,7 @@ type
private
FIsAttribute: Boolean;
FIsOptional: Boolean;
FIsNillable: Boolean;
FIsRepeating: Boolean;
FCollection: TXMLDataBindingInterface;
protected
@ -253,6 +255,7 @@ type
public
property IsAttribute: Boolean read FIsAttribute write FIsAttribute;
property IsOptional: Boolean read FIsOptional write FIsOptional;
property IsNillable: Boolean read FIsNillable write FIsNillable;
property IsReadOnly: Boolean read GetIsReadOnly;
property IsRepeating: Boolean read FIsRepeating write FIsRepeating;
property PropertyType: TXMLDataBindingPropertyType read GetPropertyType;
@ -269,6 +272,7 @@ type
function GetPropertyType(): TXMLDataBindingPropertyType; override;
public
constructor Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; const AName: String; ADataType: IXMLTypeDef);
constructor CreateFromAlias(AOwner: TXMLDataBindingGenerator; AProperty: TXMLDataBindingItemProperty; ADataType: IXMLTypeDef);
property DataType: IXMLTypeDef read FDataType;
end;
@ -338,6 +342,7 @@ const
MaxOccursUnbounded = 'unbounded';
UseOptional = 'optional';
CollectionPostfix = 'List';
AttributeNillable = 'nillable';
@ -624,8 +629,7 @@ function TXMLDataBindingGenerator.CheckElementOccurance(AElement: IXMLElementDef
if Supports(ANode, IXMLElementCompositor, compositor) then
begin
case AOccurance of
boMinOccurs: Result := (compositor.MinOccurs = 0) or
(compositor.CompositorType = ctChoice);
boMinOccurs: Result := (compositor.MinOccurs = 0);
boMaxOccurs: Result := (compositor.MaxOccurs = MaxOccursUnbounded) or
(compositor.MaxOccurs > 1);
end;
@ -669,7 +673,7 @@ var
begin
Result := False;
if Supports(AElement, IXMLElementCompositor, compositor) then
if Supports(AElement.ParentNode, IXMLElementCompositor, compositor) then
Result := (compositor.CompositorType = ctChoice) and
(compositor.ElementDefs.Count > 1);
end;
@ -766,6 +770,7 @@ end;
procedure TXMLDataBindingGenerator.ProcessChildElement(ASchema: TXMLDataBindingSchema; AElement: IXMLElementDef; AInterface: TXMLDataBindingInterface);
var
actualElement: IXMLElementDef;
propertyType: TXMLDataBindingItem;
propertyItem: TXMLDataBindingProperty;
@ -787,6 +792,16 @@ begin
IsChoice(AElement);
propertyItem.IsRepeating := IsElementRepeating(AElement);
actualElement := AElement;
while Assigned(actualElement) and Assigned(actualElement.Ref) do
actualElement := actualElement.Ref;
if AElement.HasAttribute(AttributeNillable) then
propertyItem.IsNillable := StrToBoolDef(AElement.Attributes[AttributeNillable], False)
else if actualElement.HasAttribute(AttributeNillable) then
propertyItem.IsNillable := StrToBoolDef(actualElement.Attributes[AttributeNillable], False);
AInterface.AddProperty(propertyItem);
end;
end;
@ -1440,10 +1455,7 @@ begin
if itemProperty.Item = AOldItem then
begin
{ Replace item property with simple property }
simpleProperty := TXMLDataBindingSimpleProperty.Create(Owner,
itemProperty.SchemaItem,
itemProperty.Name,
TXMLDataBindingSimpleTypeAliasItem(AOldItem).DataType);
simpleProperty := TXMLDataBindingSimpleProperty.CreateFromAlias(Owner, itemProperty, TXMLDataBindingSimpleTypeAliasItem(AOldItem).DataType);
{ FProperties owns itemProperty and will free it }
FProperties[propertyIndex] := simpleProperty;
@ -1553,6 +1565,17 @@ begin
end;
constructor TXMLDataBindingSimpleProperty.CreateFromAlias(AOwner: TXMLDataBindingGenerator; AProperty: TXMLDataBindingItemProperty; ADataType: IXMLTypeDef);
begin
Create(AOwner, AProperty.SchemaItem, AProperty.Name, ADataType);
IsAttribute := AProperty.IsAttribute;
IsOptional := AProperty.IsOptional;
IsNillable := AProperty.IsNillable;
IsRepeating := AProperty.IsRepeating;
end;
function TXMLDataBindingSimpleProperty.GetIsReadOnly(): Boolean;
begin
Result := False;