Added: XSDValidate methods to ensure:
- required elements are created (with limitations; no data content validation or default value checking is performed) - the order of Sequences is maintained
This commit is contained in:
parent
c892e495b7
commit
595ae4ea7d
@ -22,6 +22,12 @@ type
|
|||||||
TXMLTimeFragments = set of TXMLTimeFragment;
|
TXMLTimeFragments = set of TXMLTimeFragment;
|
||||||
|
|
||||||
|
|
||||||
|
IXSDValidate = interface
|
||||||
|
['{3BFDC851-7459-403B-87B3-A52E9E85BC8C}']
|
||||||
|
procedure XSDValidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
AllTimeFragments = [Low(TXMLTimeFragment)..High(TXMLTimeFragment)];
|
AllTimeFragments = [Low(TXMLTimeFragment)..High(TXMLTimeFragment)];
|
||||||
|
|
||||||
@ -41,6 +47,11 @@ const
|
|||||||
|
|
||||||
function GetNodeIsNil(ANode: IXMLNode): Boolean;
|
function GetNodeIsNil(ANode: IXMLNode): Boolean;
|
||||||
procedure SetNodeIsNil(ANode: IXMLNode; ASetNil: Boolean);
|
procedure SetNodeIsNil(ANode: IXMLNode; ASetNil: Boolean);
|
||||||
|
|
||||||
|
procedure XSDValidate(AParent: IXMLNode; ARecurse: Boolean = True; AValidateParent: Boolean = True);
|
||||||
|
procedure CreateRequiredElements(AParent: IXMLNode; ANodes: array of string);
|
||||||
|
procedure CreateRequiredAttributes(AParent: IXMLNode; ANodes: array of string);
|
||||||
|
procedure SortChildNodes(AParent: IXMLNode; ASortOrder: array of string);
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -78,9 +89,20 @@ const
|
|||||||
implementation
|
implementation
|
||||||
uses
|
uses
|
||||||
DateUtils,
|
DateUtils,
|
||||||
|
Math,
|
||||||
|
Types,
|
||||||
Windows;
|
Windows;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
PSortNodeInfo = ^TSortNodeInfo;
|
||||||
|
TSortNodeInfo = record
|
||||||
|
Node: IXMLNode;
|
||||||
|
SortIndex: Integer;
|
||||||
|
OriginalIndex: Integer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function DateTimeToXML(ADate: TDateTime; AFormat: TXMLDateTimeFormat; ATimeFragments: TXMLTimeFragments): string;
|
function DateTimeToXML(ADate: TDateTime; AFormat: TXMLDateTimeFormat; ATimeFragments: TXMLTimeFragments): string;
|
||||||
var
|
var
|
||||||
formatSettings: TFormatSettings;
|
formatSettings: TFormatSettings;
|
||||||
@ -417,5 +439,125 @@ begin
|
|||||||
ANode.AttributeNodes.Delete(XMLIsNilAttribute, XMLSchemaInstanceURI);
|
ANode.AttributeNodes.Delete(XMLIsNilAttribute, XMLSchemaInstanceURI);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function DoSortNodes(Item1, Item2: Pointer): Integer;
|
||||||
|
var
|
||||||
|
nodeInfo1: PSortNodeInfo;
|
||||||
|
nodeInfo2: PSortNodeInfo;
|
||||||
|
|
||||||
|
begin
|
||||||
|
nodeInfo1 := Item1;
|
||||||
|
nodeInfo2 := Item2;
|
||||||
|
|
||||||
|
if (nodeInfo1^.SortIndex > -1) and (nodeInfo2^.SortIndex = -1) then
|
||||||
|
Result := GreaterThanValue
|
||||||
|
|
||||||
|
else if (nodeInfo1^.SortIndex = -1) and (nodeInfo2^.SortIndex > -1) then
|
||||||
|
Result := LessThanValue
|
||||||
|
|
||||||
|
else if (nodeInfo1^.SortIndex = -1) and (nodeInfo2^.SortIndex = -1) then
|
||||||
|
Result := CompareValue(nodeInfo1^.OriginalIndex, nodeInfo2^.OriginalIndex)
|
||||||
|
|
||||||
|
else
|
||||||
|
Result := CompareValue(nodeInfo1^.SortIndex, nodeInfo2^.SortIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure XSDValidate(AParent: IXMLNode; ARecurse, AValidateParent: Boolean);
|
||||||
|
var
|
||||||
|
validate: IXSDValidate;
|
||||||
|
childIndex: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if AValidateParent and Supports(AParent, IXSDValidate, validate) then
|
||||||
|
validate.XSDValidate;
|
||||||
|
|
||||||
|
if ARecurse then
|
||||||
|
begin
|
||||||
|
for childIndex := 0 to Pred(AParent.ChildNodes.Count) do
|
||||||
|
XSDValidate(AParent.ChildNodes[childIndex], ARecurse, True);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure CreateRequiredElements(AParent: IXMLNode; ANodes: array of string);
|
||||||
|
var
|
||||||
|
nodeIndex: Integer;
|
||||||
|
node: IXMLNode;
|
||||||
|
|
||||||
|
begin
|
||||||
|
for nodeIndex := Low(ANodes) to High(ANodes) do
|
||||||
|
begin
|
||||||
|
if not Assigned(AParent.ChildNodes.FindNode(ANodes[nodeIndex])) then
|
||||||
|
begin
|
||||||
|
node := AParent.OwnerDocument.CreateElement(ANodes[nodeIndex], AParent.NamespaceURI);
|
||||||
|
AParent.ChildNodes.Add(node);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure CreateRequiredAttributes(AParent: IXMLNode; ANodes: array of string);
|
||||||
|
var
|
||||||
|
nodeIndex: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
for nodeIndex := Low(ANodes) to High(ANodes) do
|
||||||
|
begin
|
||||||
|
if not Assigned(AParent.AttributeNodes.FindNode(ANodes[nodeIndex])) then
|
||||||
|
AParent.Attributes[ANodes[nodeIndex]] := '';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure SortChildNodes(AParent: IXMLNode; ASortOrder: array of string);
|
||||||
|
var
|
||||||
|
sortList: TList;
|
||||||
|
nodeInfo: PSortNodeInfo;
|
||||||
|
childIndex: Integer;
|
||||||
|
sortIndex: Integer;
|
||||||
|
node: IXMLNode;
|
||||||
|
|
||||||
|
begin
|
||||||
|
sortList := TList.Create;
|
||||||
|
try
|
||||||
|
{ Build a list of the child nodes, with their original index and the
|
||||||
|
index in the ASortOrder array. }
|
||||||
|
for childIndex := 0 to Pred(AParent.ChildNodes.Count) do
|
||||||
|
begin
|
||||||
|
New(nodeInfo);
|
||||||
|
nodeInfo^.Node := AParent.ChildNodes[childIndex];
|
||||||
|
nodeInfo^.OriginalIndex := childIndex;
|
||||||
|
|
||||||
|
for sortIndex := Low(ASortOrder) to High(ASortOrder) do
|
||||||
|
begin
|
||||||
|
if ASortOrder[sortIndex] = nodeInfo^.Node.NodeName then
|
||||||
|
begin
|
||||||
|
nodeInfo^.SortIndex := sortIndex;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
sortList.Add(nodeInfo);
|
||||||
|
end;
|
||||||
|
|
||||||
|
sortList.Sort(DoSortNodes);
|
||||||
|
|
||||||
|
{ Rebuild the ChildNodes list }
|
||||||
|
for childIndex := 0 to Pred(sortList.Count) do
|
||||||
|
begin
|
||||||
|
node := PSortNodeInfo(sortList[childIndex])^.Node;
|
||||||
|
|
||||||
|
AParent.ChildNodes.Remove(node);
|
||||||
|
AParent.ChildNodes.Insert(childIndex, node);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
for sortIndex := 0 to Pred(sortList.Count) do
|
||||||
|
Dispose(PSortNodeInfo(sortList[sortIndex]));
|
||||||
|
|
||||||
|
FreeAndNil(sortList);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -67,6 +67,8 @@ type
|
|||||||
procedure WriteSchemaEnumeration(AStream: TStreamHelper; AItem: TXMLDataBindingEnumeration; ASection: TDelphiXMLSection);
|
procedure WriteSchemaEnumeration(AStream: TStreamHelper; AItem: TXMLDataBindingEnumeration; ASection: TDelphiXMLSection);
|
||||||
procedure WriteSchemaEnumerationArray(AStream: TStreamHelper; AItem: TXMLDataBindingEnumeration);
|
procedure WriteSchemaEnumerationArray(AStream: TStreamHelper; AItem: TXMLDataBindingEnumeration);
|
||||||
|
|
||||||
|
procedure WriteValidate(AStream: TStreamHelper; AItem: TXMLDataBindingInterface; ASection: TDelphiXMLSection);
|
||||||
|
|
||||||
function GetDelphiNodeType(AProperty: TXMLDataBindingProperty): TDelphiNodeType;
|
function GetDelphiNodeType(AProperty: TXMLDataBindingProperty): TDelphiNodeType;
|
||||||
function DataTypeConversion(const ADestination, ASource: String; ADataType: IXMLTypeDef; AAccessor: TDelphiAccessor; ANodeType: TDelphiNodeType; const ALinesBefore: String = ''): String;
|
function DataTypeConversion(const ADestination, ASource: String; ADataType: IXMLTypeDef; AAccessor: TDelphiAccessor; ANodeType: TDelphiNodeType; const ALinesBefore: String = ''): String;
|
||||||
function XMLToNativeDataType(const ADestination, ASource: String; ADataType: IXMLTypeDef; ANodeType: TDelphiNodeType; const ALinesBefore: String = ''): String;
|
function XMLToNativeDataType(const ADestination, ASource: String; ADataType: IXMLTypeDef; ANodeType: TDelphiNodeType; const ALinesBefore: String = ''): String;
|
||||||
@ -366,7 +368,7 @@ begin
|
|||||||
|
|
||||||
case AItem.ItemType of
|
case AItem.ItemType of
|
||||||
itEnumerationMember:
|
itEnumerationMember:
|
||||||
Result := TXMLDataBindingEnumerationMember(AItem).Enumeration.TranslatedName + '_' + Result;
|
Result := DelphiSafeName(TXMLDataBindingEnumerationMember(AItem).Enumeration.TranslatedName) + '_' + Result;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -566,66 +568,11 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
procedure TDelphiXMLDataBindingGenerator.WriteImplementationUses(AStream: TStreamHelper; ASchemaList: TXMLSchemaList);
|
procedure TDelphiXMLDataBindingGenerator.WriteImplementationUses(AStream: TStreamHelper; ASchemaList: TXMLSchemaList);
|
||||||
var
|
|
||||||
needsUtils: Boolean;
|
|
||||||
schemaIndex: Integer;
|
|
||||||
schema: TXMLDataBindingSchema;
|
|
||||||
itemIndex: Integer;
|
|
||||||
interfaceItem: TXMLDataBindingInterface;
|
|
||||||
propertyIndex: Integer;
|
|
||||||
propertyItem: TXMLDataBindingSimpleProperty;
|
|
||||||
typeMapping: TTypeMapping;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
needsUtils := False;
|
{ In ye olde days this is where we checked if XMLDataBindingUtils was required. With the
|
||||||
|
introduction of the IXSDValidate, this is practically always the case. }
|
||||||
{ Determine if any helper functions are used }
|
|
||||||
for schemaIndex := Pred(ASchemaList.Count) downto 0 do
|
|
||||||
begin
|
|
||||||
schema := ASchemaList[schemaIndex];
|
|
||||||
|
|
||||||
for itemIndex := Pred(schema.ItemCount) downto 0 do
|
|
||||||
begin
|
|
||||||
if schema.Items[itemIndex].ItemType = itInterface then
|
|
||||||
begin
|
|
||||||
interfaceItem := TXMLDataBindingInterface(schema.Items[itemIndex]);
|
|
||||||
|
|
||||||
for propertyIndex := Pred(interfaceItem.PropertyCount) downto 0 do
|
|
||||||
begin
|
|
||||||
if interfaceItem.Properties[propertyIndex].PropertyType = ptSimple then
|
|
||||||
begin
|
|
||||||
propertyItem := TXMLDataBindingSimpleProperty(interfaceItem.Properties[propertyIndex]);
|
|
||||||
|
|
||||||
if propertyItem.IsNillable then
|
|
||||||
begin
|
|
||||||
needsUtils := True;
|
|
||||||
Break;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if GetDataTypeMapping(propertyItem.DataType, typeMapping) then
|
|
||||||
begin
|
|
||||||
if TypeConversionReqUtils[typeMapping.Conversion] then
|
|
||||||
begin
|
|
||||||
needsUtils := True;
|
|
||||||
Break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
AStream.WriteLn('uses');
|
AStream.WriteLn('uses');
|
||||||
|
AStream.WriteLn(' SysUtils;');
|
||||||
if needsUtils then
|
|
||||||
begin
|
|
||||||
AStream.WriteLn(' SysUtils,');
|
|
||||||
AStream.WriteLn(' XMLDataBindingUtils;');
|
|
||||||
end else
|
|
||||||
AStream.WriteLn(' SysUtils;');
|
|
||||||
|
|
||||||
AStream.WriteLn;
|
AStream.WriteLn;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -726,6 +673,10 @@ begin
|
|||||||
parent := ItemClass;
|
parent := ItemClass;
|
||||||
|
|
||||||
|
|
||||||
|
if AItem.CanValidate then
|
||||||
|
parent := parent + ', ' + XSDValidateInterface;
|
||||||
|
|
||||||
|
|
||||||
AStream.WriteLnNamedFmt(InterfaceItemClass,
|
AStream.WriteLnNamedFmt(InterfaceItemClass,
|
||||||
['Name', AItem.TranslatedName,
|
['Name', AItem.TranslatedName,
|
||||||
'ParentName', parent]);
|
'ParentName', parent]);
|
||||||
@ -914,6 +865,7 @@ begin
|
|||||||
if ASection = dxsClass then
|
if ASection = dxsClass then
|
||||||
AStream.WriteLn(' protected');
|
AStream.WriteLn(' protected');
|
||||||
|
|
||||||
|
WriteValidate(AStream, AItem, ASection);
|
||||||
hasMembers := WriteSchemaInterfaceCollectionProperties(AStream, AItem, ASection);
|
hasMembers := WriteSchemaInterfaceCollectionProperties(AStream, AItem, ASection);
|
||||||
|
|
||||||
for member := Low(TDelphiXMLMember) to High(TDelphiXMLMember) do
|
for member := Low(TDelphiXMLMember) to High(TDelphiXMLMember) do
|
||||||
@ -1408,6 +1360,122 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TDelphiXMLDataBindingGenerator.WriteValidate(AStream: TStreamHelper; AItem: TXMLDataBindingInterface; ASection: TDelphiXMLSection);
|
||||||
|
var
|
||||||
|
propertyIndex: Integer;
|
||||||
|
propertyItem: TXMLDataBindingProperty;
|
||||||
|
elementSortOrder: string;
|
||||||
|
elementSortCount: Integer;
|
||||||
|
elementRequired: string;
|
||||||
|
elementRequiredCount: Integer;
|
||||||
|
attributeRequired: string;
|
||||||
|
attributeRequiredCount: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if AItem.DocumentElement then
|
||||||
|
begin
|
||||||
|
case ASection of
|
||||||
|
dxsInterface,
|
||||||
|
dxsClass:
|
||||||
|
AStream.WriteLn(XSDValidateDocumentMethodInterface);
|
||||||
|
|
||||||
|
dxsImplementation:
|
||||||
|
AStream.WriteLnNamedFmt(XSDValidateDocumentMethodImplementation,
|
||||||
|
['Name', AItem.TranslatedName]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if AItem.CanValidate then
|
||||||
|
begin
|
||||||
|
case ASection of
|
||||||
|
dxsInterface,
|
||||||
|
dxsClass:
|
||||||
|
begin
|
||||||
|
AStream.WriteLn(XSDValidateMethodInterface);
|
||||||
|
AStream.WriteLn('');
|
||||||
|
end;
|
||||||
|
|
||||||
|
dxsImplementation:
|
||||||
|
begin
|
||||||
|
AStream.WriteLnNamedFmt(XSDValidateMethodImplementationBegin,
|
||||||
|
['Name', AItem.TranslatedName]);
|
||||||
|
|
||||||
|
elementSortOrder := '';
|
||||||
|
elementSortCount := 0;
|
||||||
|
|
||||||
|
elementRequired := '';
|
||||||
|
elementRequiredCount := 0;
|
||||||
|
|
||||||
|
attributeRequired := '';
|
||||||
|
attributeRequiredCount := 0;
|
||||||
|
|
||||||
|
|
||||||
|
for propertyIndex := 0 to Pred(AItem.PropertyCount) do
|
||||||
|
begin
|
||||||
|
propertyItem := AItem.Properties[propertyIndex];
|
||||||
|
|
||||||
|
if propertyItem.IsAttribute then
|
||||||
|
begin
|
||||||
|
if not propertyItem.IsOptional then
|
||||||
|
begin
|
||||||
|
attributeRequired := attributeRequired + ', ' + QuotedStr(propertyItem.Name);
|
||||||
|
Inc(attributeRequiredCount);
|
||||||
|
end;
|
||||||
|
end else if not propertyItem.IsNodeValue then
|
||||||
|
begin
|
||||||
|
elementSortOrder := elementSortOrder + ', ' + QuotedStr(propertyItem.Name);
|
||||||
|
Inc(elementSortCount);
|
||||||
|
|
||||||
|
if (not propertyItem.IsOptional) and (not propertyItem.IsRepeating) then
|
||||||
|
begin
|
||||||
|
case propertyItem.PropertyType of
|
||||||
|
ptSimple:
|
||||||
|
begin
|
||||||
|
elementRequired := elementRequired + ', ' + QuotedStr(propertyItem.Name);
|
||||||
|
Inc(elementRequiredCount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
ptItem:
|
||||||
|
{ For Item properties, we call our getter property. This ensures the child element exists,
|
||||||
|
but also that it is created using our binding implementation. Otherwise there will be no
|
||||||
|
IXSDValidate interface to call on the newly created node. }
|
||||||
|
AStream.WriteLnNamedFmt(XSDValidateMethodImplementationComplex,
|
||||||
|
['Name', propertyItem.TranslatedName]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
if elementRequiredCount > 0 then
|
||||||
|
begin
|
||||||
|
Delete(elementRequired, 1, 2);
|
||||||
|
AStream.WriteLnNamedFmt(XSDValidateMethodImplementationRequired,
|
||||||
|
['RequiredElements', elementRequired]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
if attributeRequiredCount > 0 then
|
||||||
|
begin
|
||||||
|
Delete(attributeRequired, 1, 2);
|
||||||
|
AStream.WriteLnNamedFmt(XSDValidateMethodImplementationAttrib,
|
||||||
|
['RequiredAttributes', attributeRequired]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if elementSortCount > 1 then
|
||||||
|
begin
|
||||||
|
Delete(elementSortOrder, 1, 2);
|
||||||
|
AStream.WriteLnNamedFmt(XSDValidateMethodImplementationSort,
|
||||||
|
['SortOrder', elementSortOrder]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
AStream.WriteLn(XSDValidateMethodImplementationEnd);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TDelphiXMLDataBindingGenerator.GetDelphiNodeType(AProperty: TXMLDataBindingProperty): TDelphiNodeType;
|
function TDelphiXMLDataBindingGenerator.GetDelphiNodeType(AProperty: TXMLDataBindingProperty): TDelphiNodeType;
|
||||||
begin
|
begin
|
||||||
if AProperty.IsAttribute then
|
if AProperty.IsAttribute then
|
||||||
|
@ -25,7 +25,8 @@ const
|
|||||||
'%<UsesClause>:s' +
|
'%<UsesClause>:s' +
|
||||||
' Classes,' + CrLf +
|
' Classes,' + CrLf +
|
||||||
' XMLDoc,' + CrLf +
|
' XMLDoc,' + CrLf +
|
||||||
' XMLIntf;' + CrLf +
|
' XMLIntf,' + CrLf +
|
||||||
|
' XMLDataBindingUtils;' + CrLf +
|
||||||
'' + CrLf +
|
'' + CrLf +
|
||||||
'type' + CrLf;
|
'type' + CrLf;
|
||||||
|
|
||||||
@ -70,6 +71,30 @@ const
|
|||||||
'' + CrLf;
|
'' + CrLf;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
XSDValidateInterface = 'IXSDValidate';
|
||||||
|
|
||||||
|
XSDValidateDocumentMethodInterface = ' procedure XSDValidateDocument;';
|
||||||
|
|
||||||
|
XSDValidateDocumentMethodImplementation = 'procedure TXML%<Name>:s.XSDValidateDocument;' + CrLf +
|
||||||
|
'begin' + CrLf +
|
||||||
|
' XMLDataBindingUtils.XSDValidate(Self);' + CrLf +
|
||||||
|
'end;' + CrLf;
|
||||||
|
|
||||||
|
|
||||||
|
XSDValidateMethodInterface = ' procedure XSDValidate;';
|
||||||
|
|
||||||
|
XSDValidateMethodImplementationBegin = 'procedure TXML%<Name>:s.XSDValidate;' + CrLf +
|
||||||
|
'begin';
|
||||||
|
|
||||||
|
XSDValidateMethodImplementationRequired = ' CreateRequiredElements(Self, [%<RequiredElements>:s]);';
|
||||||
|
XSDValidateMethodImplementationComplex = ' Get%<Name>:s;';
|
||||||
|
XSDValidateMethodImplementationAttrib = ' CreateRequiredAttributes(Self, [%<RequiredAttributes>:s]);';
|
||||||
|
XSDValidateMethodImplementationSort = ' SortChildNodes(Self, [%<SortOrder>:s]);';
|
||||||
|
|
||||||
|
XSDValidateMethodImplementationEnd = 'end;' + CrLf;
|
||||||
|
|
||||||
|
|
||||||
PropertyIntfMethodGetOptional = ' function GetHas%<PropertyName>:s: Boolean;';
|
PropertyIntfMethodGetOptional = ' function GetHas%<PropertyName>:s: Boolean;';
|
||||||
PropertyIntfMethodGetNil = ' function Get%<PropertyName>:sIsNil: Boolean;';
|
PropertyIntfMethodGetNil = ' function Get%<PropertyName>:sIsNil: Boolean;';
|
||||||
PropertyIntfMethodGetText = ' function Get%<PropertyName>:sText: WideString;';
|
PropertyIntfMethodGetText = ' function Get%<PropertyName>:sText: WideString;';
|
||||||
@ -248,14 +273,14 @@ const
|
|||||||
(
|
(
|
||||||
{ dntElement } ' %<Destination>:s := ChildNodes[''%<Source>:s''].NodeValue;',
|
{ dntElement } ' %<Destination>:s := ChildNodes[''%<Source>:s''].NodeValue;',
|
||||||
{ dntAttribute } ' %<Destination>:s := AttributeNodes[''%<Source>:s''].NodeValue;',
|
{ dntAttribute } ' %<Destination>:s := AttributeNodes[''%<Source>:s''].NodeValue;',
|
||||||
{ dntNodeValue } ' %<Destination>:s := NodeValue;',
|
{ dntNodeValue } ' %<Destination>:s := GetNodeValue;',
|
||||||
{ dntCustom } ' %<Destination>:s := %<Source>:s;'
|
{ dntCustom } ' %<Destination>:s := %<Source>:s;'
|
||||||
),
|
),
|
||||||
{ daSet }
|
{ daSet }
|
||||||
(
|
(
|
||||||
{ dntElement } ' ChildNodes[''%<Destination>:s''].NodeValue := %<Source>:s;',
|
{ dntElement } ' ChildNodes[''%<Destination>:s''].NodeValue := %<Source>:s;',
|
||||||
{ dntAttribute } ' SetAttribute(''%<Destination>:s'', %<Source>:s);',
|
{ dntAttribute } ' SetAttribute(''%<Destination>:s'', %<Source>:s);',
|
||||||
{ dntNodeValue } ' NodeValue := %<Source>:s;',
|
{ dntNodeValue } ' SetNodeValue(%<Source>:s);',
|
||||||
{ dntCustom } ' %<Destination>:s := %<Source>:s;'
|
{ dntCustom } ' %<Destination>:s := %<Source>:s;'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -291,12 +316,12 @@ const
|
|||||||
(
|
(
|
||||||
{ tcNone } '',
|
{ tcNone } '',
|
||||||
{ tcBoolean } '',
|
{ tcBoolean } '',
|
||||||
{ tcFloat } ' %<Destination>:s := XMLToFloat(NodeValue);',
|
{ tcFloat } ' %<Destination>:s := XMLToFloat(GetNodeValue);',
|
||||||
{ tcDateTime } ' %<Destination>:s := XMLToDateTime(NodeValue, xdtDateTime);',
|
{ tcDateTime } ' %<Destination>:s := XMLToDateTime(GetNodeValue, xdtDateTime);',
|
||||||
{ tcDate } ' %<Destination>:s := XMLToDateTime(NodeValue, xdtDate);',
|
{ tcDate } ' %<Destination>:s := XMLToDateTime(GetNodeValue, xdtDate);',
|
||||||
{ tcTime } ' %<Destination>:s := XMLToDateTime(NodeValue, xdtTime);',
|
{ tcTime } ' %<Destination>:s := XMLToDateTime(GetNodeValue, xdtTime);',
|
||||||
{ tcString } ' %<Destination>:s := NodeValue;',
|
{ tcString } ' %<Destination>:s := GetNodeValue;',
|
||||||
{ tcBase64 } ' %<Destination>:s := Base64Decode(Trim(NodeValue));'
|
{ tcBase64 } ' %<Destination>:s := Base64Decode(Trim(GetNodeValue));'
|
||||||
),
|
),
|
||||||
{ dntCustom}
|
{ dntCustom}
|
||||||
(
|
(
|
||||||
@ -337,13 +362,13 @@ const
|
|||||||
{ dntNodeValue }
|
{ dntNodeValue }
|
||||||
(
|
(
|
||||||
{ tcNone } '',
|
{ tcNone } '',
|
||||||
{ tcBoolean } ' NodeValue := BoolToXML(%<Source>:s);',
|
{ tcBoolean } ' SetNodeValue(BoolToXML(%<Source>:s));',
|
||||||
{ tcFloat } ' NodeValue := FloatToXML(%<Source>:s);',
|
{ tcFloat } ' SetNodeValue(FloatToXML(%<Source>:s));',
|
||||||
{ tcDateTime } ' NodeValue := DateTimeToXML(%<Source>:s, xdtDateTime);',
|
{ tcDateTime } ' SetNodeValue(DateTimeToXML(%<Source>:s, xdtDateTime));',
|
||||||
{ tcDate } ' NodeValue := DateTimeToXML(%<Source>:s, xdtDate);',
|
{ tcDate } ' SetNodeValue(DateTimeToXML(%<Source>:s, xdtDate));',
|
||||||
{ tcTime } ' NodeValue := DateTimeToXML(%<Source>:s, xdtTime);',
|
{ tcTime } ' SetNodeValue(DateTimeToXML(%<Source>:s, xdtTime));',
|
||||||
{ tcString } '',
|
{ tcString } '',
|
||||||
{ tcBase64 } ' NodeValue := Base64Encode(%<Source>:s);'
|
{ tcBase64 } ' SetNodeValue(Base64Encode(%<Source>:s));'
|
||||||
),
|
),
|
||||||
{ dntCustom}
|
{ dntCustom}
|
||||||
(
|
(
|
||||||
|
@ -72,7 +72,7 @@ type
|
|||||||
function FindInterface(ASchema: TXMLDataBindingSchema; const AName: String; AType: TXMLDataBindingInterfaceType): TXMLDataBindingInterface;
|
function FindInterface(ASchema: TXMLDataBindingSchema; const AName: String; AType: TXMLDataBindingInterfaceType): TXMLDataBindingInterface;
|
||||||
|
|
||||||
procedure FindEnumerationProc(AItem: TXMLDataBindingItem; AData: Pointer; var AAbort: Boolean);
|
procedure FindEnumerationProc(AItem: TXMLDataBindingItem; AData: Pointer; var AAbort: Boolean);
|
||||||
function FindEnumeration(ASchema: TXMLDataBindingSchema; const AName: String): TXMLDataBindingEnumeration;
|
function FindEnumeration(ASchema: TXMLDataBindingSchema; const AName: String; AAttribute: Boolean): TXMLDataBindingEnumeration;
|
||||||
|
|
||||||
procedure ReplaceItem(const AOldItem, ANewItem: TXMLDataBindingItem);
|
procedure ReplaceItem(const AOldItem, ANewItem: TXMLDataBindingItem);
|
||||||
|
|
||||||
@ -81,6 +81,7 @@ type
|
|||||||
procedure ResolveItem(ASchema: TXMLDataBindingSchema; AItem: TXMLDataBindingUnresolvedItem);
|
procedure ResolveItem(ASchema: TXMLDataBindingSchema; AItem: TXMLDataBindingUnresolvedItem);
|
||||||
procedure ResolveNameConflicts;
|
procedure ResolveNameConflicts;
|
||||||
|
|
||||||
|
|
||||||
procedure PostProcessSchema(ASchema: TXMLDataBindingSchema);
|
procedure PostProcessSchema(ASchema: TXMLDataBindingSchema);
|
||||||
procedure PostProcessItem(ASchema: TXMLDataBindingSchema; AItem: TXMLDataBindingItem);
|
procedure PostProcessItem(ASchema: TXMLDataBindingSchema; AItem: TXMLDataBindingItem);
|
||||||
function TranslateItemName(AItem: TXMLDataBindingItem): String; virtual;
|
function TranslateItemName(AItem: TXMLDataBindingItem): String; virtual;
|
||||||
@ -194,12 +195,14 @@ type
|
|||||||
TXMLDataBindingInterface = class(TXMLDataBindingItem)
|
TXMLDataBindingInterface = class(TXMLDataBindingItem)
|
||||||
private
|
private
|
||||||
FInterfaceType: TXMLDataBindingInterfaceType;
|
FInterfaceType: TXMLDataBindingInterfaceType;
|
||||||
|
FIsSequence: Boolean;
|
||||||
FProperties: TObjectList;
|
FProperties: TObjectList;
|
||||||
FBaseName: String;
|
FBaseName: String;
|
||||||
FBaseItem: TXMLDataBindingInterface;
|
FBaseItem: TXMLDataBindingInterface;
|
||||||
|
|
||||||
function GetProperties(Index: Integer): TXMLDataBindingProperty;
|
function GetProperties(Index: Integer): TXMLDataBindingProperty;
|
||||||
function GetPropertyCount: Integer;
|
function GetPropertyCount: Integer;
|
||||||
|
function GetCanValidate: Boolean;
|
||||||
protected
|
protected
|
||||||
function GetItemType: TXMLDataBindingItemType; override;
|
function GetItemType: TXMLDataBindingItemType; override;
|
||||||
|
|
||||||
@ -213,7 +216,9 @@ type
|
|||||||
property BaseName: String read FBaseName write FBaseName;
|
property BaseName: String read FBaseName write FBaseName;
|
||||||
property BaseItem: TXMLDataBindingInterface read FBaseItem write FBaseItem;
|
property BaseItem: TXMLDataBindingInterface read FBaseItem write FBaseItem;
|
||||||
|
|
||||||
|
property CanValidate: Boolean read GetCanValidate;
|
||||||
property InterfaceType: TXMLDataBindingInterfaceType read FInterfaceType;
|
property InterfaceType: TXMLDataBindingInterfaceType read FInterfaceType;
|
||||||
|
property IsSequence: Boolean read FIsSequence;
|
||||||
|
|
||||||
property PropertyCount: Integer read GetPropertyCount;
|
property PropertyCount: Integer read GetPropertyCount;
|
||||||
property Properties[Index: Integer]: TXMLDataBindingProperty read GetProperties;
|
property Properties[Index: Integer]: TXMLDataBindingProperty read GetProperties;
|
||||||
@ -234,18 +239,20 @@ type
|
|||||||
|
|
||||||
TXMLDataBindingEnumeration = class(TXMLDataBindingItem)
|
TXMLDataBindingEnumeration = class(TXMLDataBindingItem)
|
||||||
private
|
private
|
||||||
FMembers: TObjectList;
|
FMembers: TObjectList;
|
||||||
|
FIsAttribute: Boolean;
|
||||||
|
|
||||||
function GetMemberCount: Integer;
|
function GetMemberCount: Integer;
|
||||||
function GetMembers(Index: Integer): TXMLDataBindingEnumerationMember;
|
function GetMembers(Index: Integer): TXMLDataBindingEnumerationMember;
|
||||||
protected
|
protected
|
||||||
function GetItemType: TXMLDataBindingItemType; override;
|
function GetItemType: TXMLDataBindingItemType; override;
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; AEnumerations: IXMLEnumerationCollection; const AName: String);
|
constructor Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; AEnumerations: IXMLEnumerationCollection; const AName: String; AIsAttribute: Boolean);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
property MemberCount: Integer read GetMemberCount;
|
property MemberCount: Integer read GetMemberCount;
|
||||||
property Members[Index: Integer]: TXMLDataBindingEnumerationMember read GetMembers;
|
property Members[Index: Integer]: TXMLDataBindingEnumerationMember read GetMembers;
|
||||||
|
property IsAttribute: Boolean read FIsAttribute;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -307,12 +314,14 @@ type
|
|||||||
TXMLDataBindingUnresolvedItem = class(TXMLDataBindingItem)
|
TXMLDataBindingUnresolvedItem = class(TXMLDataBindingItem)
|
||||||
private
|
private
|
||||||
FInterfaceType: TXMLDataBindingInterfaceType;
|
FInterfaceType: TXMLDataBindingInterfaceType;
|
||||||
|
FIsAttribute: Boolean;
|
||||||
protected
|
protected
|
||||||
function GetItemType: TXMLDataBindingItemType; override;
|
function GetItemType: TXMLDataBindingItemType; override;
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; const AName: String; AInterfaceType: TXMLDataBindingInterfaceType);
|
constructor Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; const AName: String; AInterfaceType: TXMLDataBindingInterfaceType; AIsAttribute: Boolean);
|
||||||
|
|
||||||
property InterfaceType: TXMLDataBindingInterfaceType read FInterfaceType;
|
property InterfaceType: TXMLDataBindingInterfaceType read FInterfaceType;
|
||||||
|
property IsAttribute: Boolean read FIsAttribute;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -581,9 +590,10 @@ end;
|
|||||||
|
|
||||||
procedure TXMLDataBindingGenerator.GenerateElementObjects(ASchema: TXMLDataBindingSchema; ARootDocument: Boolean);
|
procedure TXMLDataBindingGenerator.GenerateElementObjects(ASchema: TXMLDataBindingSchema; ARootDocument: Boolean);
|
||||||
var
|
var
|
||||||
schemaDef: IXMLSchemaDef;
|
schemaDef: IXMLSchemaDef;
|
||||||
elementIndex: Integer;
|
elementIndex: Integer;
|
||||||
item: TXMLDataBindingItem;
|
item: TXMLDataBindingItem;
|
||||||
|
attributeIndex: Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
schemaDef := ASchema.SchemaDef;
|
schemaDef := ASchema.SchemaDef;
|
||||||
@ -595,6 +605,9 @@ begin
|
|||||||
if Assigned(item) and ARootDocument then
|
if Assigned(item) and ARootDocument then
|
||||||
item.DocumentElement := True;
|
item.DocumentElement := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
for attributeIndex := 0 to Pred(schemaDef.AttributeDefs.Count) do
|
||||||
|
ProcessElement(ASchema, schemaDef.AttributeDefs[attributeIndex]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -646,7 +659,7 @@ begin
|
|||||||
|
|
||||||
if simpleType.Enumerations.Count > 0 then
|
if simpleType.Enumerations.Count > 0 then
|
||||||
begin
|
begin
|
||||||
enumerationObject := TXMLDataBindingEnumeration.Create(Self, simpleType, simpleType.Enumerations, simpleType.Name);
|
enumerationObject := TXMLDataBindingEnumeration.Create(Self, simpleType, simpleType.Enumerations, simpleType.Name, False);
|
||||||
ASchema.AddItem(enumerationObject);
|
ASchema.AddItem(enumerationObject);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -724,6 +737,7 @@ var
|
|||||||
simpleAliasItem: TXMLDataBindingSimpleTypeAliasItem;
|
simpleAliasItem: TXMLDataBindingSimpleTypeAliasItem;
|
||||||
elementIndex: Integer;
|
elementIndex: Integer;
|
||||||
simpleTypeDef: IXMLSimpleTypeDef;
|
simpleTypeDef: IXMLSimpleTypeDef;
|
||||||
|
typeDef: IXMLTypeDef;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
@ -736,7 +750,7 @@ begin
|
|||||||
|
|
||||||
if not Assigned(Result) then
|
if not Assigned(Result) then
|
||||||
begin
|
begin
|
||||||
Result := TXMLDataBindingUnresolvedItem.Create(Self, AElement, AElement.Ref.Name, ifElement);
|
Result := TXMLDataBindingUnresolvedItem.Create(Self, AElement, AElement.Ref.Name, ifElement, False);
|
||||||
ASchema.AddItem(Result);
|
ASchema.AddItem(Result);
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
@ -750,7 +764,7 @@ begin
|
|||||||
|
|
||||||
if not Assigned(Result) then
|
if not Assigned(Result) then
|
||||||
begin
|
begin
|
||||||
Result := TXMLDataBindingUnresolvedItem.Create(Self, AElement, AElement.DataTypeName, ifComplexType);
|
Result := TXMLDataBindingUnresolvedItem.Create(Self, AElement, AElement.DataTypeName, ifComplexType, True);
|
||||||
ASchema.AddItem(Result);
|
ASchema.AddItem(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -767,11 +781,11 @@ begin
|
|||||||
if simpleTypeDef.Enumerations.Count > 0 then
|
if simpleTypeDef.Enumerations.Count > 0 then
|
||||||
begin
|
begin
|
||||||
{ References enumeration. }
|
{ References enumeration. }
|
||||||
Result := FindEnumeration(ASchema, AElement.DataTypeName);
|
Result := FindEnumeration(ASchema, AElement.DataTypeName, False);
|
||||||
|
|
||||||
if not Assigned(Result) then
|
if not Assigned(Result) then
|
||||||
begin
|
begin
|
||||||
Result := TXMLDataBindingUnresolvedItem.Create(Self, AElement, AElement.DataTypeName, ifEnumeration);
|
Result := TXMLDataBindingUnresolvedItem.Create(Self, AElement, AElement.DataTypeName, ifEnumeration, False);
|
||||||
ASchema.AddItem(Result);
|
ASchema.AddItem(Result);
|
||||||
end;
|
end;
|
||||||
end else if simpleTypeDef.IsBuiltInType and AElement.IsGlobal then
|
end else if simpleTypeDef.IsBuiltInType and AElement.IsGlobal then
|
||||||
@ -791,7 +805,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.Enumerations, AElement.Name);
|
enumerationObject := TXMLDataBindingEnumeration.Create(Self, AElement, AElement.DataType.Enumerations, AElement.Name, False);
|
||||||
ASchema.AddItem(enumerationObject);
|
ASchema.AddItem(enumerationObject);
|
||||||
Result := enumerationObject;
|
Result := enumerationObject;
|
||||||
end else if AElement.DataType.IsComplex then
|
end else if AElement.DataType.IsComplex then
|
||||||
@ -812,6 +826,29 @@ begin
|
|||||||
|
|
||||||
for attributeIndex := 0 to Pred(AElement.AttributeDefs.Count) do
|
for attributeIndex := 0 to Pred(AElement.AttributeDefs.Count) do
|
||||||
ProcessAttribute(ASchema, AElement.AttributeDefs[attributeIndex], interfaceObject);
|
ProcessAttribute(ASchema, AElement.AttributeDefs[attributeIndex], interfaceObject);
|
||||||
|
end else if AElement.IsGlobal then
|
||||||
|
begin
|
||||||
|
{ Non-anonymous non-complex type. Assume somewhere in there is a
|
||||||
|
built-in type.
|
||||||
|
|
||||||
|
This code probably isn't correct, but it works for the files I got. }
|
||||||
|
typeDef := AElement.DataType;
|
||||||
|
|
||||||
|
while Assigned(typeDef) do
|
||||||
|
begin
|
||||||
|
if Supports(typeDef, IXMLSimpleTypeDef, simpleTypeDef) and (simpleTypeDef.IsBuiltInType) then
|
||||||
|
begin
|
||||||
|
{ The element is global, but only references a simple type. }
|
||||||
|
simpleAliasItem := TXMLDataBindingSimpleTypeAliasItem.Create(Self, AElement, AElement.Name);
|
||||||
|
simpleAliasItem.DataType := typeDef;
|
||||||
|
ASchema.AddItem(simpleAliasItem);
|
||||||
|
|
||||||
|
Result := simpleAliasItem;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
typeDef := typeDef.BaseType;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -820,11 +857,12 @@ end;
|
|||||||
|
|
||||||
function TXMLDataBindingGenerator.ProcessElement(ASchema: TXMLDataBindingSchema; AAttribute: IXMLAttributeDef): TXMLDataBindingItem;
|
function TXMLDataBindingGenerator.ProcessElement(ASchema: TXMLDataBindingSchema; AAttribute: IXMLAttributeDef): TXMLDataBindingItem;
|
||||||
var
|
var
|
||||||
enumerationObject: TXMLDataBindingEnumeration;
|
enumerationObject: TXMLDataBindingEnumeration;
|
||||||
interfaceObject: TXMLDataBindingInterface;
|
interfaceObject: TXMLDataBindingInterface;
|
||||||
complexAliasItem: TXMLDataBindingComplexTypeAliasItem;
|
complexAliasItem: TXMLDataBindingComplexTypeAliasItem;
|
||||||
simpleAliasItem: TXMLDataBindingSimpleTypeAliasItem;
|
simpleAliasItem: TXMLDataBindingSimpleTypeAliasItem;
|
||||||
simpleTypeDef: IXMLSimpleTypeDef;
|
simpleTypeDef: IXMLSimpleTypeDef;
|
||||||
|
typeDef: IXMLTypeDef;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
@ -836,7 +874,7 @@ begin
|
|||||||
|
|
||||||
if not Assigned(Result) then
|
if not Assigned(Result) then
|
||||||
begin
|
begin
|
||||||
Result := TXMLDataBindingUnresolvedItem.Create(Self, AAttribute, AAttribute.Ref.Name, ifElement);
|
Result := TXMLDataBindingUnresolvedItem.Create(Self, AAttribute, AAttribute.Ref.Name, ifElement, True);
|
||||||
ASchema.AddItem(Result);
|
ASchema.AddItem(Result);
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
@ -850,7 +888,7 @@ begin
|
|||||||
|
|
||||||
if not Assigned(Result) then
|
if not Assigned(Result) then
|
||||||
begin
|
begin
|
||||||
Result := TXMLDataBindingUnresolvedItem.Create(Self, AAttribute, AAttribute.DataTypeName, ifComplexType);
|
Result := TXMLDataBindingUnresolvedItem.Create(Self, AAttribute, AAttribute.DataTypeName, ifComplexType, True);
|
||||||
ASchema.AddItem(Result);
|
ASchema.AddItem(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -867,11 +905,11 @@ begin
|
|||||||
if simpleTypeDef.Enumerations.Count > 0 then
|
if simpleTypeDef.Enumerations.Count > 0 then
|
||||||
begin
|
begin
|
||||||
{ References enumeration. }
|
{ References enumeration. }
|
||||||
Result := FindEnumeration(ASchema, AAttribute.DataTypeName);
|
Result := FindEnumeration(ASchema, AAttribute.DataTypeName, True);
|
||||||
|
|
||||||
if not Assigned(Result) then
|
if not Assigned(Result) then
|
||||||
begin
|
begin
|
||||||
Result := TXMLDataBindingUnresolvedItem.Create(Self, AAttribute, AAttribute.DataTypeName, ifEnumeration);
|
Result := TXMLDataBindingUnresolvedItem.Create(Self, AAttribute, AAttribute.DataTypeName, ifEnumeration, True);
|
||||||
ASchema.AddItem(Result);
|
ASchema.AddItem(Result);
|
||||||
end;
|
end;
|
||||||
end else if simpleTypeDef.IsBuiltInType and AAttribute.IsGlobal then
|
end else if simpleTypeDef.IsBuiltInType and AAttribute.IsGlobal then
|
||||||
@ -891,7 +929,7 @@ begin
|
|||||||
if AAttribute.DataType.Enumerations.Count > 0 then
|
if AAttribute.DataType.Enumerations.Count > 0 then
|
||||||
begin
|
begin
|
||||||
{ Enumeration }
|
{ Enumeration }
|
||||||
enumerationObject := TXMLDataBindingEnumeration.Create(Self, AAttribute, AAttribute.DataType.Enumerations, AAttribute.Name);
|
enumerationObject := TXMLDataBindingEnumeration.Create(Self, AAttribute, AAttribute.DataType.Enumerations, AAttribute.Name, True);
|
||||||
ASchema.AddItem(enumerationObject);
|
ASchema.AddItem(enumerationObject);
|
||||||
Result := enumerationObject;
|
Result := enumerationObject;
|
||||||
end else if AAttribute.DataType.IsComplex then
|
end else if AAttribute.DataType.IsComplex then
|
||||||
@ -903,6 +941,29 @@ begin
|
|||||||
|
|
||||||
ASchema.AddItem(interfaceObject);
|
ASchema.AddItem(interfaceObject);
|
||||||
Result := interfaceObject;
|
Result := interfaceObject;
|
||||||
|
end else if AAttribute.IsGlobal then
|
||||||
|
begin
|
||||||
|
{ Non-anonymous non-complex type. Assume somewhere in there is a
|
||||||
|
built-in type.
|
||||||
|
|
||||||
|
This code probably isn't correct, but it works for the files I got. }
|
||||||
|
typeDef := AAttribute.DataType;
|
||||||
|
|
||||||
|
while Assigned(typeDef) do
|
||||||
|
begin
|
||||||
|
if Supports(typeDef, IXMLSimpleTypeDef, simpleTypeDef) and (simpleTypeDef.IsBuiltInType) then
|
||||||
|
begin
|
||||||
|
{ The element is global, but only references a simple type. }
|
||||||
|
simpleAliasItem := TXMLDataBindingSimpleTypeAliasItem.Create(Self, AAttribute, AAttribute.Name);
|
||||||
|
simpleAliasItem.DataType := typeDef;
|
||||||
|
ASchema.AddItem(simpleAliasItem);
|
||||||
|
|
||||||
|
Result := simpleAliasItem;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
typeDef := typeDef.BaseType;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1015,6 +1076,12 @@ type
|
|||||||
Name: String;
|
Name: String;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
PFindEnumerationInfo = ^TFindEnumerationInfo;
|
||||||
|
TFindEnumerationInfo = record
|
||||||
|
Attribute: Boolean;
|
||||||
|
Name: String;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TXMLDataBindingGenerator.FindInterfaceProc(AItem: TXMLDataBindingItem; AData: Pointer; var AAbort: Boolean);
|
procedure TXMLDataBindingGenerator.FindInterfaceProc(AItem: TXMLDataBindingItem; AData: Pointer; var AAbort: Boolean);
|
||||||
var
|
var
|
||||||
@ -1051,15 +1118,25 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
procedure TXMLDataBindingGenerator.FindEnumerationProc(AItem: TXMLDataBindingItem; AData: Pointer; var AAbort: Boolean);
|
procedure TXMLDataBindingGenerator.FindEnumerationProc(AItem: TXMLDataBindingItem; AData: Pointer; var AAbort: Boolean);
|
||||||
|
var
|
||||||
|
findInfo: PFindEnumerationInfo;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
AAbort := (AItem.ItemType = itEnumeration) and
|
findInfo := PFindEnumerationInfo(AData);
|
||||||
(AItem.Name = PChar(AData));
|
AAbort := (AItem.ItemType = itEnumeration) and
|
||||||
|
(AItem.Name = findInfo^.Name) and
|
||||||
|
(TXMLDataBindingEnumeration(AItem).IsAttribute = findInfo^.Attribute);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TXMLDataBindingGenerator.FindEnumeration(ASchema: TXMLDataBindingSchema; const AName: String): TXMLDataBindingEnumeration;
|
function TXMLDataBindingGenerator.FindEnumeration(ASchema: TXMLDataBindingSchema; const AName: String; AAttribute: Boolean): TXMLDataBindingEnumeration;
|
||||||
|
var
|
||||||
|
findInfo: TFindEnumerationInfo;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := TXMLDataBindingEnumeration(IterateSchemaItems(ASchema, FindEnumerationProc, PChar(AName)));
|
findInfo.Attribute := AAttribute;
|
||||||
|
findInfo.Name := AName;
|
||||||
|
Result := TXMLDataBindingEnumeration(IterateSchemaItems(ASchema, FindEnumerationProc, @findInfo));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1158,14 +1235,14 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
|
|
||||||
if AItem.InterfaceType = ifEnumeration then
|
if AItem.InterfaceType = ifEnumeration then
|
||||||
referenceItem := FindEnumeration(ASchema, AItem.Name)
|
referenceItem := FindEnumeration(ASchema, AItem.Name, AItem.IsAttribute)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
referenceItem := FindInterface(ASchema, AItem.Name, AItem.InterfaceType);
|
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, AItem.IsAttribute);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if Assigned(referenceItem) then
|
if Assigned(referenceItem) then
|
||||||
@ -1285,6 +1362,13 @@ begin
|
|||||||
Inc(depth);
|
Inc(depth);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ test }
|
||||||
|
if not resolved then
|
||||||
|
begin
|
||||||
|
newName := newName + IntToStr(Succ(itemIndex));
|
||||||
|
resolved := True;
|
||||||
|
end;
|
||||||
|
|
||||||
if resolved then
|
if resolved then
|
||||||
begin
|
begin
|
||||||
items.Delete(itemIndex);
|
items.Delete(itemIndex);
|
||||||
@ -1325,8 +1409,41 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
{ Translate name }
|
{ Translate name }
|
||||||
AItem.TranslatedName := TranslateItemName(AItem);
|
AItem.TranslatedName := TranslateItemName(AItem);
|
||||||
|
|
||||||
|
{ Process members }
|
||||||
|
case AItem.ItemType of
|
||||||
|
itInterface:
|
||||||
|
begin
|
||||||
|
interfaceItem := TXMLDataBindingInterface(AItem);
|
||||||
|
|
||||||
|
if (not Assigned(interfaceItem.BaseItem)) and
|
||||||
|
(Length(interfaceItem.BaseName) > 0) then
|
||||||
|
begin
|
||||||
|
{ Assume this is a reference to a simple type }
|
||||||
|
if Supports(interfaceItem.SchemaItem, IXMLTypedSchemaItem, typedSchemaItem) then
|
||||||
|
begin
|
||||||
|
propertyItem := TXMLDataBindingSimpleProperty.Create(Self, interfaceItem.SchemaItem, 'Value',
|
||||||
|
typedSchemaItem.DataType.BaseType);
|
||||||
|
propertyItem.IsNodeValue := True;
|
||||||
|
|
||||||
|
interfaceItem.AddProperty(propertyItem);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
for propertyIndex := 0 to Pred(interfaceItem.PropertyCount) do
|
||||||
|
PostProcessItem(ASchema, interfaceItem.Properties[propertyIndex]);
|
||||||
|
end;
|
||||||
|
itEnumeration:
|
||||||
|
begin
|
||||||
|
enumerationItem := TXMLDataBindingEnumeration(AItem);
|
||||||
|
|
||||||
|
for memberIndex := 0 to Pred(enumerationItem.MemberCount) do
|
||||||
|
PostProcessItem(ASchema, enumerationItem.Members[memberIndex]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Extract collections }
|
{ Extract collections }
|
||||||
if AItem.ItemType = itInterface then
|
if AItem.ItemType = itInterface then
|
||||||
@ -1381,40 +1498,6 @@ begin
|
|||||||
FreeAndNil(repeatingItems);
|
FreeAndNil(repeatingItems);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Process members }
|
|
||||||
case AItem.ItemType of
|
|
||||||
itInterface:
|
|
||||||
begin
|
|
||||||
interfaceItem := TXMLDataBindingInterface(AItem);
|
|
||||||
|
|
||||||
if (not Assigned(interfaceItem.BaseItem)) and
|
|
||||||
(Length(interfaceItem.BaseName) > 0) then
|
|
||||||
begin
|
|
||||||
{ Assume this is a reference to a simple type }
|
|
||||||
if Supports(interfaceItem.SchemaItem, IXMLTypedSchemaItem, typedSchemaItem) then
|
|
||||||
begin
|
|
||||||
propertyItem := TXMLDataBindingSimpleProperty.Create(Self, interfaceItem.SchemaItem, 'NodeValue',
|
|
||||||
typedSchemaItem.DataType.BaseType);
|
|
||||||
propertyItem.IsNodeValue := True;
|
|
||||||
|
|
||||||
interfaceItem.AddProperty(propertyItem);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
for propertyIndex := 0 to Pred(interfaceItem.PropertyCount) do
|
|
||||||
PostProcessItem(ASchema, interfaceItem.Properties[propertyIndex]);
|
|
||||||
end;
|
|
||||||
itEnumeration:
|
|
||||||
begin
|
|
||||||
enumerationItem := TXMLDataBindingEnumeration(AItem);
|
|
||||||
|
|
||||||
for memberIndex := 0 to Pred(enumerationItem.MemberCount) do
|
|
||||||
PostProcessItem(ASchema, enumerationItem.Members[memberIndex]);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1599,11 +1682,31 @@ end;
|
|||||||
|
|
||||||
{ TXMLDataBindingInterface }
|
{ TXMLDataBindingInterface }
|
||||||
constructor TXMLDataBindingInterface.Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; const AName: String);
|
constructor TXMLDataBindingInterface.Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; const AName: String);
|
||||||
|
var
|
||||||
|
elementDef: IXMLElementDef;
|
||||||
|
compositor: IXMLElementCompositor;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwner, ASchemaItem, AName);
|
inherited Create(AOwner, ASchemaItem, AName);
|
||||||
|
|
||||||
FProperties := TObjectList.Create(True);
|
FProperties := TObjectList.Create(True);
|
||||||
FInterfaceType := GetInterfaceType(SchemaItem);
|
FInterfaceType := GetInterfaceType(SchemaItem);
|
||||||
|
FIsSequence := False;
|
||||||
|
|
||||||
|
if Supports(ASchemaItem, IXMLElementDef, elementDef) then
|
||||||
|
begin
|
||||||
|
{ To access the compositor, we need to go through a ChildElement's ParentNode.
|
||||||
|
|
||||||
|
Tried but did not work:
|
||||||
|
ASchemaItem as IXMLElementCompositor
|
||||||
|
ASchemaItem.ChildNodes[0] as IXMLElementCompositor
|
||||||
|
}
|
||||||
|
if elementDef.ChildElements.Count > 0 then
|
||||||
|
begin
|
||||||
|
if Supports(elementDef.ChildElements[0].ParentNode, IXMLElementCompositor, compositor) then
|
||||||
|
FIsSequence := (compositor.CompositorType = ctSequence);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1660,6 +1763,48 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TXMLDataBindingInterface.GetCanValidate: Boolean;
|
||||||
|
var
|
||||||
|
propertyIndex: Integer;
|
||||||
|
elementCount: Integer;
|
||||||
|
requiredCount: Integer;
|
||||||
|
propertyItem: TXMLDataBindingProperty;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
elementCount := 0;
|
||||||
|
requiredCount := 0;
|
||||||
|
|
||||||
|
for propertyIndex := 0 to Pred(PropertyCount) do
|
||||||
|
begin
|
||||||
|
propertyItem := Properties[propertyIndex];
|
||||||
|
|
||||||
|
if propertyItem.IsAttribute then
|
||||||
|
begin
|
||||||
|
if not propertyItem.IsOptional then
|
||||||
|
Inc(requiredCount);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
Inc(elementCount);
|
||||||
|
if not propertyItem.IsOptional then
|
||||||
|
Inc(requiredCount);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ If there's a required element or attribute,
|
||||||
|
we can validate their presence. }
|
||||||
|
if requiredCount > 0 then
|
||||||
|
Result := True
|
||||||
|
|
||||||
|
{ If our children are a sequence and there's at least two elements,
|
||||||
|
we can validate their order. }
|
||||||
|
else if IsSequence and (elementCount > 1) then
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TXMLDataBindingInterface.GetItemType: TXMLDataBindingItemType;
|
function TXMLDataBindingInterface.GetItemType: TXMLDataBindingItemType;
|
||||||
begin
|
begin
|
||||||
Result := itInterface;
|
Result := itInterface;
|
||||||
@ -1694,14 +1839,15 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
{ TXMLDataBindingEnumeration }
|
{ TXMLDataBindingEnumeration }
|
||||||
constructor TXMLDataBindingEnumeration.Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; AEnumerations: IXMLEnumerationCollection; const AName: String);
|
constructor TXMLDataBindingEnumeration.Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; AEnumerations: IXMLEnumerationCollection; const AName: String; AIsAttribute: Boolean);
|
||||||
var
|
var
|
||||||
memberIndex: Integer;
|
memberIndex: Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwner, ASchemaItem, AName);
|
inherited Create(AOwner, ASchemaItem, AName);
|
||||||
|
|
||||||
FMembers := TObjectList.Create;
|
FMembers := TObjectList.Create;
|
||||||
|
FIsAttribute := AIsAttribute;
|
||||||
|
|
||||||
for memberIndex := 0 to Pred(AEnumerations.Count) do
|
for memberIndex := 0 to Pred(AEnumerations.Count) do
|
||||||
FMembers.Add(TXMLDataBindingEnumerationMember.Create(Owner, Self, AEnumerations.Items[memberIndex].Value));
|
FMembers.Add(TXMLDataBindingEnumerationMember.Create(Owner, Self, AEnumerations.Items[memberIndex].Value));
|
||||||
@ -1804,11 +1950,12 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
{ TXMLDataBindingUnresolvedItem }
|
{ TXMLDataBindingUnresolvedItem }
|
||||||
constructor TXMLDataBindingUnresolvedItem.Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; const AName: String; AInterfaceType: TXMLDataBindingInterfaceType);
|
constructor TXMLDataBindingUnresolvedItem.Create(AOwner: TXMLDataBindingGenerator; ASchemaItem: IXMLSchemaItem; const AName: String; AInterfaceType: TXMLDataBindingInterfaceType; AIsAttribute: Boolean);
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwner, ASchemaItem, AName);
|
inherited Create(AOwner, ASchemaItem, AName);
|
||||||
|
|
||||||
FInterfaceType := AInterfaceType;
|
FInterfaceType := AInterfaceType;
|
||||||
|
FIsAttribute := AIsAttribute;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<Borland.Personality>Delphi.Personality</Borland.Personality>
|
<Borland.Personality>Delphi.Personality</Borland.Personality>
|
||||||
<Borland.ProjectType />
|
<Borland.ProjectType />
|
||||||
<BorlandProject>
|
<BorlandProject>
|
||||||
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters><Parameters Name="RunParams">"P:\test\XMLDataBinding\Tests\Data\04. Type with attributes.xsd"</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1043</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Source><Source Name="MainSource">X2XMLDataBinding.dpr</Source></Source></Delphi.Personality></BorlandProject></BorlandProject>
|
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters><Parameters Name="RunParams">"P:\test\XMLDataBinding\Tests\Data\01. Basic simple and complex types.xsd"</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1043</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Source><Source Name="MainSource">X2XMLDataBinding.dpr</Source></Source></Delphi.Personality></BorlandProject></BorlandProject>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
|
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Loading…
Reference in New Issue
Block a user