1
0
mirror of synced 2024-11-15 03:23:51 +00:00

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:
Mark van Renswoude 2010-07-15 10:57:03 +00:00
parent c892e495b7
commit 595ae4ea7d
5 changed files with 526 additions and 144 deletions

View File

@ -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)];
@ -42,6 +48,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
XMLSchemaInstanceURI = 'http://www.w3.org/2001/XMLSchema-instance'; XMLSchemaInstanceURI = 'http://www.w3.org/2001/XMLSchema-instance';
@ -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.

View File

@ -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');
if needsUtils then
begin
AStream.WriteLn(' SysUtils,');
AStream.WriteLn(' XMLDataBindingUtils;');
end else
AStream.WriteLn(' SysUtils;'); 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

View File

@ -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}
( (

View File

@ -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;
@ -235,17 +240,19 @@ 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;
@ -584,6 +593,7 @@ 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;
@ -825,6 +862,7 @@ var
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
findInfo := PFindEnumerationInfo(AData);
AAbort := (AItem.ItemType = itEnumeration) and AAbort := (AItem.ItemType = itEnumeration) and
(AItem.Name = PChar(AData)); (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);
@ -1327,6 +1411,39 @@ 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,7 +1839,7 @@ 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;
@ -1702,6 +1847,7 @@ 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;

View File

@ -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>