From b1bba371cea7234f6271d339e3e68a1c7a276348 Mon Sep 17 00:00:00 2001 From: Philipp Winkel Date: Fri, 30 Oct 2020 08:41:26 +0100 Subject: [PATCH 1/9] =?UTF-8?q?[WIP]=20cx=20Komponenten=20durch=20Delphi?= =?UTF-8?q?=20eigene=20ersetzt=20DPROJ=20Search=20Path=20f=C3=BCr=20x2=20Z?= =?UTF-8?q?usatzkomponenten=20gesetzt,=20sp=C3=A4ter=20in=20Submodule=20au?= =?UTF-8?q?slagern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Forms/MainFrm.dfm | 102 +++++++++++++++++------------------------ Forms/MainFrm.pas | 21 +++++---- X2XMLDataBinding.dproj | 5 +- 3 files changed, 55 insertions(+), 73 deletions(-) diff --git a/Forms/MainFrm.dfm b/Forms/MainFrm.dfm index 641bd33..d859bea 100644 --- a/Forms/MainFrm.dfm +++ b/Forms/MainFrm.dfm @@ -27,19 +27,6 @@ object MainForm: TMainForm Height = 13 Caption = 'Schema file:' end - object feSchema: TcxButtonEdit - Left = 99 - Top = 8 - Anchors = [akLeft, akTop, akRight] - Properties.Buttons = < - item - Kind = bkEllipsis - end> - Properties.OnButtonClick = feSchemaPropertiesButtonClick - Properties.OnChange = feSchemaPropertiesChange - TabOrder = 0 - Width = 331 - end object gbOutput: TGroupBox Left = 8 Top = 43 @@ -47,7 +34,7 @@ object MainForm: TMainForm Height = 225 Anchors = [akLeft, akTop, akBottom] Caption = ' Output ' - TabOrder = 1 + TabOrder = 0 DesignSize = ( 422 225) @@ -82,10 +69,6 @@ object MainForm: TMainForm TabOrder = 2 object spFile: TTabSheet TabVisible = False - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object lblFile: TLabel Left = 4 Top = 7 @@ -93,23 +76,17 @@ object MainForm: TMainForm Height = 13 Caption = 'Output file:' end - object feFile: TcxButtonEdit - Left = 88 - Top = 4 - Properties.Buttons = < - item - Kind = bkEllipsis - end> - Properties.OnButtonClick = feFilePropertiesButtonClick + object feFile: TEdit + Left = 76 + Top = 3 + Width = 316 + Height = 21 TabOrder = 0 - Width = 317 + Text = 'D:\Temp\test.pas' end end object spFolder: TTabSheet TabVisible = False - DesignSize = ( - 408 - 83) object lblFolder: TLabel Left = 4 Top = 7 @@ -131,30 +108,36 @@ object MainForm: TMainForm Height = 13 Caption = 'File postfix:' end - object deFolder: TcxButtonEdit - Left = 88 - Top = 4 - Anchors = [akLeft, akTop, akRight] - Properties.Buttons = < - item - Kind = bkEllipsis - end> - Properties.OnButtonClick = deFolderPropertiesButtonClick + object edtFolderPrefix: TEdit + Left = 89 + Top = 31 + Width = 316 + Height = 21 TabOrder = 0 - Width = 317 + Text = 'Edit1' end - object edtFolderPrefix: TcxTextEdit - Left = 88 - Top = 29 + object edtFolderPostfix: TEdit + Left = 89 + Top = 59 + Width = 316 + Height = 21 TabOrder = 1 - Text = 'xml_' - Width = 121 + Text = 'Edit1' end - object edtFolderPostfix: TcxTextEdit - Left = 88 - Top = 55 + object deFolder: TEdit + Left = 89 + Top = 4 + Width = 256 + Height = 21 TabOrder = 2 - Width = 121 + end + object BrowseOutputFolderButton: TButton + Left = 351 + Top = 4 + Width = 64 + Height = 22 + Caption = 'BrowseOutputFolderButton' + TabOrder = 3 end end end @@ -200,7 +183,7 @@ object MainForm: TMainForm Anchors = [akRight, akBottom] Cancel = True Caption = '&Close' - TabOrder = 4 + TabOrder = 2 OnClick = btnCloseClick end object btnHints: TButton @@ -211,19 +194,16 @@ object MainForm: TMainForm Anchors = [akRight, akBottom] Cancel = True Caption = 'Generate blank &Hints file' - TabOrder = 2 + TabOrder = 1 OnClick = btnHintsClick end - object DefaultEditStyle: TcxDefaultEditStyleController - Style.HotTrack = False - Left = 264 - Top = 60 - PixelsPerInch = 96 - end - object LookAndFeel: TcxLookAndFeelController - Kind = lfFlat - Left = 368 - Top = 60 + object feSchema: TJvFilenameEdit + Left = 104 + Top = 8 + Width = 316 + Height = 21 + TabOrder = 4 + Text = 'feSchema' end object dlgSchema: TOpenDialog Filter = 'W3C XML Schema files (*.xsd)|*.xsd|All files (*.*)|*.*' diff --git a/Forms/MainFrm.pas b/Forms/MainFrm.pas index b902384..b45d313 100644 --- a/Forms/MainFrm.pas +++ b/Forms/MainFrm.pas @@ -13,7 +13,9 @@ uses StdCtrls, XMLDOM, XMLIntf, - + DataBindingHintsXML, + XMLDataBindingGenerator, JvExMask, JvToolEdit + { cxButtonEdit, cxContainer, cxControls, @@ -22,8 +24,8 @@ uses cxMaskEdit, cxTextEdit, - DataBindingHintsXML, - XMLDataBindingGenerator, cxGraphics, cxLookAndFeelPainters, cxClasses; + cxGraphics, cxLookAndFeelPainters, cxClasses} + ; type @@ -31,21 +33,14 @@ type btnClose: TButton; btnGenerate: TButton; btnHints: TButton; - DefaultEditStyle: TcxDefaultEditStyleController; - deFolder: TcxButtonEdit; dlgOutputFile: TSaveDialog; dlgSchema: TOpenDialog; - edtFolderPostfix: TcxTextEdit; - edtFolderPrefix: TcxTextEdit; - feFile: TcxButtonEdit; - feSchema: TcxButtonEdit; gbOutput: TGroupBox; lblFile: TLabel; lblFolder: TLabel; lblFolderPostfix: TLabel; lblFolderPrefix: TLabel; lblSchema: TLabel; - LookAndFeel: TcxLookAndFeelController; plOutput: TPageControl; rbFile: TRadioButton; rbFolder: TRadioButton; @@ -53,6 +48,12 @@ type spFolder: TTabSheet; cbHasChecksEmpty: TCheckBox; cbGenerateGetOptionalOrDefault: TCheckBox; + edtFolderPrefix: TEdit; + edtFolderPostfix: TEdit; + feFile: TEdit; + deFolder: TEdit; + feSchema: TJvFilenameEdit; + BrowseOutputFolderButton: TButton; procedure btnCloseClick(Sender: TObject); procedure btnGenerateClick(Sender: TObject); diff --git a/X2XMLDataBinding.dproj b/X2XMLDataBinding.dproj index cd277d4..081bb05 100644 --- a/X2XMLDataBinding.dproj +++ b/X2XMLDataBinding.dproj @@ -52,6 +52,7 @@ 1043 $(BDS)\bin\default_app.manifest X2XMLDataBinding + ..\x2utils;..\x2log;$(DCC_UnitSearchPath) Data.Win;Datasnap.Win;Web.Win;Soap.Win;Bde;$(DCC_Namespace) @@ -133,8 +134,8 @@ X2XMLDataBinding.dpr - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components + Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver + Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server From 6d0265862d1fc2fbf22c879a34e5b863161a0e5a Mon Sep 17 00:00:00 2001 From: Philipp Winkel Date: Fri, 30 Oct 2020 08:47:54 +0100 Subject: [PATCH 2/9] =?UTF-8?q?Fix=20TargetNamespace=20bei=20Collection=20?= =?UTF-8?q?Items=20(behebt=20Fehler=20"Interface=20nicht=20unterst=C3=BCtz?= =?UTF-8?q?t")?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Units/DelphiXMLDataBindingGenerator.pas | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Units/DelphiXMLDataBindingGenerator.pas b/Units/DelphiXMLDataBindingGenerator.pas index c570eae..d8ff615 100644 --- a/Units/DelphiXMLDataBindingGenerator.pas +++ b/Units/DelphiXMLDataBindingGenerator.pas @@ -814,12 +814,13 @@ begin 'ItemClass', GetDataTypeName(propertyItem, False)]); end; - AWriter.WriteLineNamedFmt(' %:s := CreateCollection(%:s, %:s, ''%:s'') as %:s;', + AWriter.WriteLineNamedFmt(' %:s := CreateCollection(%:s, %:s, ''%:s'', ''%:s'') as %:s;', ['FieldName', PrefixField + propertyItem.TranslatedName, 'CollectionClass', PrefixClass + propertyItem.Collection.TranslatedName, 'CollectionInterface', PrefixInterface + propertyItem.Collection.TranslatedName, 'ItemInterface', GetDataTypeName(propertyItem, True), - 'ItemSourceName', propertyItem.Name]); + 'ItemSourceName', propertyItem.Name, + 'Namespace', propertyItem.TargetNamespace]); end; end; From 5e1fa91e85abf1ef5a4aa70138a67136adb4f992 Mon Sep 17 00:00:00 2001 From: Philipp Winkel Date: Mon, 2 Nov 2020 09:34:03 +0100 Subject: [PATCH 3/9] Various Bugfixes for Filename Input --- Forms/MainFrm.dfm | 36 +++++++++++++++++++++--------------- Forms/MainFrm.pas | 26 +++++++++++++++++--------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/Forms/MainFrm.dfm b/Forms/MainFrm.dfm index d859bea..adf8064 100644 --- a/Forms/MainFrm.dfm +++ b/Forms/MainFrm.dfm @@ -69,6 +69,9 @@ object MainForm: TMainForm TabOrder = 2 object spFile: TTabSheet TabVisible = False + DesignSize = ( + 408 + 83) object lblFile: TLabel Left = 4 Top = 7 @@ -76,13 +79,15 @@ object MainForm: TMainForm Height = 13 Caption = 'Output file:' end - object feFile: TEdit - Left = 76 + object feFile: TJvFilenameEdit + Left = 89 Top = 3 Width = 316 Height = 21 + DialogOptions = [ofHideReadOnly, ofCreatePrompt] + Anchors = [akLeft, akTop, akRight] TabOrder = 0 - Text = 'D:\Temp\test.pas' + Text = '' end end object spFolder: TTabSheet @@ -114,7 +119,6 @@ object MainForm: TMainForm Width = 316 Height = 21 TabOrder = 0 - Text = 'Edit1' end object edtFolderPostfix: TEdit Left = 89 @@ -122,22 +126,22 @@ object MainForm: TMainForm Width = 316 Height = 21 TabOrder = 1 - Text = 'Edit1' end object deFolder: TEdit Left = 89 Top = 4 - Width = 256 + Width = 245 Height = 21 TabOrder = 2 end - object BrowseOutputFolderButton: TButton - Left = 351 - Top = 4 - Width = 64 + object deFolderPropertiesButton: TButton + Left = 340 + Top = 3 + Width = 65 Height = 22 - Caption = 'BrowseOutputFolderButton' + Caption = 'Properties' TabOrder = 3 + OnClick = deFolderPropertiesButtonClick end end end @@ -202,19 +206,21 @@ object MainForm: TMainForm Top = 8 Width = 316 Height = 21 + OnAfterDialog = feSchemaAfterDialog + DialogOptions = [ofHideReadOnly, ofFileMustExist] TabOrder = 4 - Text = 'feSchema' + Text = '' end object dlgSchema: TOpenDialog Filter = 'W3C XML Schema files (*.xsd)|*.xsd|All files (*.*)|*.*' Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing] - Left = 212 + Left = 284 Top = 40 end object dlgOutputFile: TSaveDialog Filter = 'Delphi source files (*.pas)|*.pas|All files (*.*)|*.*' Options = [ofHideReadOnly, ofPathMustExist, ofEnableSizing] - Left = 323 - Top = 45 + Left = 387 + Top = 37 end end diff --git a/Forms/MainFrm.pas b/Forms/MainFrm.pas index b45d313..5bbfecc 100644 --- a/Forms/MainFrm.pas +++ b/Forms/MainFrm.pas @@ -50,20 +50,22 @@ type cbGenerateGetOptionalOrDefault: TCheckBox; edtFolderPrefix: TEdit; edtFolderPostfix: TEdit; - feFile: TEdit; deFolder: TEdit; feSchema: TJvFilenameEdit; - BrowseOutputFolderButton: TButton; + deFolderPropertiesButton: TButton; + feFile: TJvFilenameEdit; procedure btnCloseClick(Sender: TObject); procedure btnGenerateClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure OutputTypeClick(Sender: TObject); procedure feFilePropertiesButtonClick(Sender: TObject; AButtonIndex: Integer); - procedure deFolderPropertiesButtonClick(Sender: TObject; AButtonIndex: Integer); + procedure deFolderPropertiesButtonClick(Sender: TObject); procedure feSchemaPropertiesButtonClick(Sender: TObject; AButtonIndex: Integer); procedure feSchemaPropertiesChange(Sender: TObject); procedure btnHintsClick(Sender: TObject); + procedure feSchemaAfterDialog(Sender: TObject; var AName: string; + var AAction: Boolean); private function CheckValidSchemaFile: Boolean; function CheckReadOnly(const AFileName: String): Boolean; @@ -174,11 +176,11 @@ begin if rbFile.Checked then begin - if not CheckReadOnly(feFile.Text) then + if not CheckReadOnly(feFile.FileName) then Exit; generator.OutputType := otSingle; - generator.OutputPath := feFile.Text; + generator.OutputPath := feFile.FileName; end else if rbFolder.Checked then begin generator.OutputType := otMultiple; @@ -188,9 +190,9 @@ begin generator.HasChecksEmpty := cbHasChecksEmpty.Checked; generator.HasGenerateGetOptionalOrDefault := cbGenerateGetOptionalOrDefault.Checked; generator.OnGetFileName := GetFileName; - generator.Execute(feSchema.Text); + generator.Execute(feSchema.Filename); - SaveSettings(feSchema.Text); + SaveSettings(feSchema.FileName); ShowMessage('The data binding has been generated.'); finally @@ -223,7 +225,7 @@ begin end; -procedure TMainForm.deFolderPropertiesButtonClick(Sender: TObject; AButtonIndex: Integer); +procedure TMainForm.deFolderPropertiesButtonClick(Sender: TObject); var directory: String; @@ -233,6 +235,12 @@ begin end; +procedure TMainForm.feSchemaAfterDialog(Sender: TObject; var AName: string; + var AAction: Boolean); +begin + feFile.FileName := ChangeFileExt(AName, '.pas'); +end; + procedure TMainForm.feSchemaPropertiesButtonClick(Sender: TObject; AButtonIndex: Integer); begin if dlgSchema.Execute then @@ -331,7 +339,7 @@ end; function TMainForm.CheckValidSchemaFile: Boolean; begin - Result := FileExists(feSchema.Text); + Result := FileExists(feSchema.FileName); if not Result then begin From ede9c973464333e47270ed011a10f5dcc5f75722 Mon Sep 17 00:00:00 2001 From: Philipp Winkel Date: Mon, 2 Nov 2020 10:09:20 +0100 Subject: [PATCH 4/9] delete XMLDataBindingUtils since it used togaether in x2utils as searchpath --- Shared/XMLDataBindingUtils.pas | 908 --------------------------------- 1 file changed, 908 deletions(-) delete mode 100644 Shared/XMLDataBindingUtils.pas diff --git a/Shared/XMLDataBindingUtils.pas b/Shared/XMLDataBindingUtils.pas deleted file mode 100644 index 2b0d80d..0000000 --- a/Shared/XMLDataBindingUtils.pas +++ /dev/null @@ -1,908 +0,0 @@ -{ - Helpers functions for the X2Software XML Data Binding - - Last changed: $Date$ - Revision: $Rev$ - URL: $URL$ -} -unit XMLDataBindingUtils; - -interface -uses - Classes, - SysUtils, - XMLDoc, - xmldom, - XMLIntf; - - -type - EBase64Error = class(Exception); - - TXMLDateTimeFormat = (xdtDateTime, xdtDate, xdtTime); - TXMLTimeFragment = (xtfMilliseconds, xtfTimezone); - TXMLTimeFragments = set of TXMLTimeFragment; - - - IXSDValidate = interface - ['{3BFDC851-7459-403B-87B3-A52E9E85BC8C}'] - procedure XSDValidate; - end; - - - TX2XMLNode = class(TXMLNode) - private - function GetChildNodesNS(const ANodeName, ANamespaceURI: DOMString): IXMLNode; - protected - property ChildNodesNS[const ANodeName, ANamespaceURI: DOMString]: IXMLNode read GetChildNodesNS; - end; - - - TX2XMLNodeCollection = class(TXMLNodeCollection) - private - function GetChildNodesNS(const ANodeName, ANamespaceURI: DOMString): IXMLNode; - protected - property ChildNodesNS[const ANodeName, ANamespaceURI: DOMString]: IXMLNode read GetChildNodesNS; - end; - - - TXMLNodeCollectionEnumerator = class(TInterfacedObject) - private - FNodeCollection: IXMLNodeCollection; - FIndex: Integer; - public - constructor Create(ANodeCollection: IXMLNodeCollection); - - function GetCurrent: IXMLNode; - function MoveNext: Boolean; virtual; - - property Current: IXMLNode read GetCurrent; - end; - - - -const - AllTimeFragments = [Low(TXMLTimeFragment)..High(TXMLTimeFragment)]; - - - - function DateTimeToXML(ADate: TDateTime; AFormat: TXMLDateTimeFormat; ATimeFragments: TXMLTimeFragments = AllTimeFragments): string; - function XMLToDateTime(const ADate: string; AFormat: TXMLDateTimeFormat): TDateTime; - - function BoolToXML(AValue: Boolean): WideString; - function XMLToBool(const AValue: WideString): Boolean; - - function FloatToXML(AValue: Extended): WideString; - function XMLToFloat(const AValue: WideString): Extended; - - function GetNodeIsNil(ANode: IXMLNode): 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); - - - { Now wraps the JclMime implementation: - Lightening fast Mime (Base64) Encoding and Decoding routines. - Coded by Ralf Junker (ralfjunker@gmx.de).} - function Base64Encode(AValue: String): String; - function Base64Decode(AValue: String): String; - procedure Base64DecodeToStream(AValue: String; AStream: TStream); - procedure Base64DecodeToFile(AValue: String; const AFileName: String); - -const - XMLSchemaInstanceURI = 'http://www.w3.org/2001/XMLSchema-instance'; - - XMLDateFormat = 'yyyy"-"mm"-"dd'; - XMLTimeFormat = 'hh":"nn":"ss'; - XMLMsecsFormat = '"."zzz'; - XMLTimezoneZulu = 'Z'; - XMLTimezoneFormat = '%s%.2d:%.2d'; - - XMLDateTimeFormats: array[TXMLDateTimeFormat] of String = - ( - XMLDateFormat + '"T"' + XMLTimeFormat, - XMLDateFormat, - XMLTimeFormat - ); - - XMLTimezoneSigns: array[Boolean] of Char = ('-', '+'); - XMLBoolValues: array[Boolean] of String = - ( - 'false', - 'true' - ); - - XMLIsNilAttribute = 'nil'; - XMLIsNilAttributeNS = 'xsi:nil'; - - Base64ValidChars = ['A'..'Z', 'a'..'z', '0'..'9', '+', '/']; - Base64LookupTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + - 'abcdefghijklmnopqrstuvwxyz' + - '0123456789+/'; - Base64Padding = '='; - - -implementation -uses - DateUtils, - Math, - Types, - Windows; - - -type - PSortNodeInfo = ^TSortNodeInfo; - TSortNodeInfo = record - Node: IXMLNode; - SortIndex: Integer; - OriginalIndex: Integer; - end; - - - function MimeEncodeString(const S: AnsiString): AnsiString; forward; - function MimeDecodeString(const S: AnsiString): AnsiString; forward; - procedure MimeEncodeStream(const InputStream: TStream; const OutputStream: TStream); forward; - procedure MimeDecodeStream(const InputStream: TStream; const OutputStream: TStream); forward; - function MimeEncodedSize(const I: Cardinal): Cardinal; forward; - function MimeDecodedSize(const I: Cardinal): Cardinal; forward; - procedure MimeEncode(var InputBuffer; const InputByteCount: Cardinal; var OutputBuffer); forward; - function MimeDecode(var InputBuffer; const InputBytesCount: Cardinal; var OutputBuffer): Cardinal; forward; - function MimeDecodePartial(var InputBuffer; const InputBytesCount: Cardinal; var OutputBuffer; var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal; forward; - function MimeDecodePartialEnd(var OutputBuffer; const ByteBuffer: Cardinal; const ByteBufferSpace: Cardinal): Cardinal; forward; - - - -{ TX2XMLNode } -function TX2XMLNode.GetChildNodesNS(const ANodeName, ANamespaceURI: DOMString): IXMLNode; -begin - Result := ChildNodes.FindNode(ANodeName, ANamespaceURI); - if (not Assigned(Result)) and (doNodeAutoCreate in OwnerDocument.Options) then - Result := AddChild(ANodeName, ANamespaceURI); -end; - - - -{ TX2XMLNodeCollection } -function TX2XMLNodeCollection.GetChildNodesNS(const ANodeName, ANamespaceURI: DOMString): IXMLNode; -begin - Result := ChildNodes.FindNode(ANodeName, ANamespaceURI); - if (not Assigned(Result)) and (doNodeAutoCreate in OwnerDocument.Options) then - Result := AddChild(ANodeName, ANamespaceURI); -end; - - - -{ TXMLNodeCollectionEnumerator } -constructor TXMLNodeCollectionEnumerator.Create(ANodeCollection: IXMLNodeCollection); -begin - inherited Create; - - FNodeCollection := ANodeCollection; - FIndex := -1; -end; - - -function TXMLNodeCollectionEnumerator.GetCurrent: IXMLNode; -begin - if (FIndex >= 0) and (FIndex < FNodeCollection.Count) then - Result := FNodeCollection.Nodes[FIndex] - else - Result := nil; -end; - - -function TXMLNodeCollectionEnumerator.MoveNext: Boolean; -begin - Inc(FIndex); - Result := (FIndex < FNodeCollection.Count); -end; - - - -function DateTimeToXML(ADate: TDateTime; AFormat: TXMLDateTimeFormat; ATimeFragments: TXMLTimeFragments): string; -var - formatSettings: TFormatSettings; - timeZone: TTimeZoneInformation; - timeOffset: Integer; - -begin - GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, formatSettings); - Result := FormatDateTime(XMLDateTimeFormats[AFormat], ADate, formatSettings); - - if AFormat in [xdtDateTime, xdtTime] then - begin - if xtfMilliseconds in ATimeFragments then - Result := Result + FormatDateTime(XMLMsecsFormat, ADate); - - if xtfTimezone in ATimeFragments then - begin - FillChar(timeZone, SizeOf(TTimeZoneInformation), #0); - if GetTimeZoneInformation(timeZone) <> TIME_ZONE_ID_INVALID then - begin - timeOffset := -timeZone.Bias; - - if timeOffset = 0 then - Result := Result + XMLTimezoneZulu - else - Result := Result + Format(XMLTimezoneFormat, - [XMLTimezoneSigns[timeOffset > 0], - Abs(timeZone.Bias div 60), - Abs(timeZone.Bias mod 60)]); - end; - end; - end; -end; - - -function XMLToDateTime(const ADate: string; AFormat: TXMLDateTimeFormat): TDateTime; -const - { yyyy-mm-ddThh:nn:ss.zzz+xx:xx } - XMLTimeSeparatorPos = 11; - XMLTimeSeparator = 'T'; - XMLMinTimeLength = 8; - -var - date: string; - time: string; - year: Integer; - month: Integer; - day: Integer; - hour: Integer; - minute: Integer; - second: Integer; - msec: Integer; - hasTimezone: Boolean; - xmlOffset: Integer; - timeZone: TTimeZoneInformation; - localOffset: Integer; - -begin - Result := 0; - date := ''; - time := ''; - - case AFormat of - xdtDateTime: - begin - if (Length(ADate) < XMLTimeSeparatorPos) or - (ADate[XMLTimeSeparatorPos] <> XMLTimeSeparator) then - Exit; - - date := ADate; - time := ADate; - SetLength(date, Pred(XMLTimeSeparatorPos)); - Delete(time, 1, XMLTimeSeparatorPos); - end; - - xdtDate: - begin - if Length(ADate) < Pred(XMLTimeSeparatorPos) then - Exit; - - date := ADate; - end; - - xdtTime: - begin - if Length(ADate) < XMLMinTimeLength then - Exit; - - time := ADate; - end; - end; - - if AFormat in [xdtDateTime, xdtDate] then - begin - { Parse date (yyyy-mm-hh) } - if TryStrToInt(Copy(date, 1, 4), year) and - TryStrToInt(Copy(date, 6, 2), month) and - TryStrToInt(Copy(date, 9, 2), day) then - Result := EncodeDate(year, month, day); - end; - - if AFormat in [xdtDateTime, xdtTime] then - begin - { Parse time (hh:nn:ss) } - if TryStrToInt(Copy(time, 1, 2), hour) and - TryStrToInt(Copy(time, 4, 2), minute) and - TryStrToInt(Copy(time, 7, 2), second) then - begin - msec := 0; - Delete(time, 1, 8); - - if Length(time) > 0 then - begin - if time[1] = '.' then - begin - { Parse milliseconds (.zzz) } - if not TryStrToInt(Copy(time, 2, 3), msec) then - msec := 0; - - Delete(time, 1, 4); - end; - end; - - Result := Result + EncodeTime(hour, minute, second, msec); - - if Length(time) > 0 then - begin - hasTimezone := False; - xmlOffset := 0; - - if time[1] = XMLTimezoneZulu then - begin - { Zulu time } - hasTimezone := True; - end else if time[1] in [XMLTimezoneSigns[False], XMLTimezoneSigns[True]] then - begin - { Parse timezone ([+|-]xx:xx) } - if TryStrToInt(Copy(time, 2, 2), hour) and - TryStrToInt(Copy(time, 5, 2), minute) then - begin - xmlOffset := (hour * MinsPerHour) + minute; - hasTimezone := True; - - if time[1] = XMLTimezoneSigns[False] then - xmlOffset := -xmlOffset; - end; - end; - - if hasTimezone then - begin - FillChar(timeZone, SizeOf(TTimeZoneInformation), #0); - if GetTimeZoneInformation(timeZone) <> TIME_ZONE_ID_INVALID then - begin - localOffset := -timeZone.Bias; - Result := IncMinute(Result, localOffset - xmlOffset); - end; - end; - end; - end; - end; -end; - - -function BoolToXML(AValue: Boolean): WideString; -begin - Result := XMLBoolValues[AValue]; -end; - - -function XMLToBool(const AValue: WideString): Boolean; -begin - Result := StrToBoolDef(AValue, False); -end; - - -function GetXMLFloatFormatSettings(): TFormatSettings; -begin - Result.DecimalSeparator := '.'; -end; - - -function FloatToXML(AValue: Extended): WideString; -begin - Result := FloatToStr(AValue, GetXMLFloatFormatSettings()); -end; - - -function XMLToFloat(const AValue: WideString): Extended; -begin - Result := StrToFloat(AValue, GetXMLFloatFormatSettings()); -end; - - -function Base64Encode(AValue: String): String; -begin - Result := MimeEncodeString(AValue); -end; - - -function Base64Decode(AValue: String): String; -begin - Result := MimeDecodeString(AValue); -end; - - -procedure Base64DecodeToStream(AValue: String; AStream: TStream); -var - input: TStringStream; - -begin - input := TStringStream.Create(AValue); - try - MimeDecodeStream(input, AStream); - finally - FreeAndNil(input); - end; -end; - - -procedure Base64DecodeToFile(AValue: String; const AFileName: String); -var - input: TStringStream; - output: TFileStream; - -begin - input := TStringStream.Create(AValue); - try - output := TFileStream.Create(AFileName, fmCreate or fmShareDenyWrite); - try - MimeDecodeStream(input, output); - finally - FreeAndNil(output); - end; - finally - FreeAndNil(input); - end; -end; - - -function GetNodeIsNil(ANode: IXMLNode): Boolean; -begin - Result := ANode.HasAttribute(XMLIsNilAttribute, XMLSchemaInstanceURI) and - XMLToBool(ANode.GetAttributeNS(XMLIsNilAttribute, XMLSchemaInstanceURI)); -end; - - -procedure SetNodeIsNil(ANode: IXMLNode; ASetNil: Boolean); -var - documentElement: IXMLNode; - -begin - if ASetNil then - begin - ANode.ChildNodes.Clear; - - documentElement := ANode.OwnerDocument.DocumentElement; - if not documentElement.HasAttribute('xmlns:xsi') then - documentElement.SetAttributeNS('xmlns:xsi', '', XMLSchemaInstanceURI); - - ANode.SetAttributeNS(XMLIsNilAttributeNS, XMLSchemaInstanceURI, BoolToXML(True)); - end else - ANode.AttributeNodes.Delete(XMLIsNilAttribute, XMLSchemaInstanceURI); -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 = nodeInfo2^.SortIndex) 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; - - -{ --- JclMime implementation from here. } -// Caution: For MimeEncodeStream and all other kinds of multi-buffered -// Mime encodings (i.e. Files etc.), BufferSize must be set to a multiple of 3. -// Even though the implementation of the Mime decoding routines below -// do not require a particular buffer size, they work fastest with sizes of -// multiples of four. The chosen size is a multiple of 3 and of 4 as well. -// The following numbers are, in addition, also divisible by 1024: -// $2400, $3000, $3C00, $4800, $5400, $6000, $6C00. - -const - BUFFER_SIZE = $3000; - EqualSign = Byte('='); - - MIME_ENCODE_TABLE: array [0..63] of Byte = ( - 65, 66, 67, 68, 69, 70, 71, 72, // 00 - 07 - 73, 74, 75, 76, 77, 78, 79, 80, // 08 - 15 - 81, 82, 83, 84, 85, 86, 87, 88, // 16 - 23 - 89, 90, 97, 98, 99, 100, 101, 102, // 24 - 31 - 103, 104, 105, 106, 107, 108, 109, 110, // 32 - 39 - 111, 112, 113, 114, 115, 116, 117, 118, // 40 - 47 - 119, 120, 121, 122, 48, 49, 50, 51, // 48 - 55 - 52, 53, 54, 55, 56, 57, 43, 47); // 56 - 63 - - MIME_DECODE_TABLE: array [Byte] of Cardinal = ( - 255, 255, 255, 255, 255, 255, 255, 255, // 00 - 07 - 255, 255, 255, 255, 255, 255, 255, 255, // 08 - 15 - 255, 255, 255, 255, 255, 255, 255, 255, // 16 - 23 - 255, 255, 255, 255, 255, 255, 255, 255, // 24 - 31 - 255, 255, 255, 255, 255, 255, 255, 255, // 32 - 39 - 255, 255, 255, 62, 255, 255, 255, 63, // 40 - 47 - 52, 53, 54, 55, 56, 57, 58, 59, // 48 - 55 - 60, 61, 255, 255, 255, 255, 255, 255, // 56 - 63 - 255, 0, 1, 2, 3, 4, 5, 6, // 64 - 71 - 7, 8, 9, 10, 11, 12, 13, 14, // 72 - 79 - 15, 16, 17, 18, 19, 20, 21, 22, // 80 - 87 - 23, 24, 25, 255, 255, 255, 255, 255, // 88 - 95 - 255, 26, 27, 28, 29, 30, 31, 32, // 96 - 103 - 33, 34, 35, 36, 37, 38, 39, 40, // 104 - 111 - 41, 42, 43, 44, 45, 46, 47, 48, // 112 - 119 - 49, 50, 51, 255, 255, 255, 255, 255, // 120 - 127 - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255); - -type - PByte4 = ^TByte4; - TByte4 = packed record - B1: Byte; - B2: Byte; - B3: Byte; - B4: Byte; - end; - - PByte3 = ^TByte3; - TByte3 = packed record - B1: Byte; - B2: Byte; - B3: Byte; - end; - - -//------------------------------------------------------------------------------ -// Wrapper functions & procedures -//------------------------------------------------------------------------------ - -function MimeEncodeString(const S: AnsiString): AnsiString; -var - L: Cardinal; -begin - L := Length(S); - if L > 0 then - begin - SetLength(Result, MimeEncodedSize(L)); - MimeEncode(PChar(S)^, L, PChar(Result)^); - end - else - Result := ''; -end; - -//------------------------------------------------------------------------------ - -function MimeDecodeString(const S: AnsiString): AnsiString; -var - ByteBuffer, ByteBufferSpace: Cardinal; - L: Cardinal; -begin - L := Length(S); - if L > 0 then - begin - SetLength(Result, MimeDecodedSize(L)); - ByteBuffer := 0; - ByteBufferSpace := 4; - L := MimeDecodePartial(PChar(S)^, L, PChar(Result)^, ByteBuffer, ByteBufferSpace); - Inc(L, MimeDecodePartialEnd(PChar(Cardinal(Result) + L)^, ByteBuffer, ByteBufferSpace)); - SetLength(Result, L); - end; -end; - -//------------------------------------------------------------------------------ - -procedure MimeEncodeStream(const InputStream: TStream; const OutputStream: TStream); -var - InputBuffer: array [0..BUFFER_SIZE - 1] of Byte; - OutputBuffer: array [0..((BUFFER_SIZE + 2) div 3) * 4 - 1] of Byte; - BytesRead: Integer; -begin - BytesRead := InputStream.Read(InputBuffer, SizeOf(InputBuffer)); - while BytesRead > 0 do - begin - MimeEncode(InputBuffer, BytesRead, OutputBuffer); - OutputStream.Write(OutputBuffer, MimeEncodedSize(BytesRead)); - BytesRead := InputStream.Read(InputBuffer, SizeOf(InputBuffer)); - end; -end; - -//------------------------------------------------------------------------------ - -procedure MimeDecodeStream(const InputStream: TStream; const OutputStream: TStream); -var - ByteBuffer, ByteBufferSpace: Cardinal; - InputBuffer: array [0..(BUFFER_SIZE + 3) div 4 * 3 - 1] of Byte; - OutputBuffer: array [0..BUFFER_SIZE - 1] of Byte; - BytesRead: Integer; -begin - ByteBuffer := 0; - ByteBufferSpace := 4; - BytesRead := InputStream.Read(InputBuffer, SizeOf(InputBuffer)); - while BytesRead > 0 do - begin - OutputStream.Write(OutputBuffer, MimeDecodePartial(InputBuffer, BytesRead, OutputBuffer, ByteBuffer, ByteBufferSpace)); - BytesRead := InputStream.Read(InputBuffer, SizeOf(InputBuffer)); - end; - OutputStream.Write(OutputBuffer, MimeDecodePartialEnd(OutputBuffer, ByteBuffer, ByteBufferSpace)); -end; - -//------------------------------------------------------------------------------ -// Helper functions -//------------------------------------------------------------------------------ - -function MimeEncodedSize(const I: Cardinal): Cardinal; -begin - Result := (I + 2) div 3 * 4; -end; - -//------------------------------------------------------------------------------ - -function MimeDecodedSize(const I: Cardinal): Cardinal; -begin - Result := (I + 3) div 4 * 3; -end; - -//------------------------------------------------------------------------------ -// Primary functions & procedures -//------------------------------------------------------------------------------ - -procedure MimeEncode(var InputBuffer; const InputByteCount: Cardinal; var OutputBuffer); -var - B: Cardinal; - InMax3: Cardinal; - InPtr, InLimitPtr: ^Byte; - OutPtr: PByte4; -begin - if InputByteCount <= 0 then - Exit; - - InPtr := @InputBuffer; - InMax3 := InputByteCount div 3 * 3; - OutPTr := @OutputBuffer; - Cardinal(InLimitPtr) := Cardinal(InPtr) + InMax3; - - while InPtr <> InLimitPtr do - begin - B := InPtr^; - B := B shl 8; - Inc(InPtr); - B := B or InPtr^; - B := B shl 8; - Inc(InPtr); - B := B or InPtr^; - Inc(InPtr); - // Write 4 bytes to OutputBuffer (in reverse order). - OutPtr.B4 := MIME_ENCODE_TABLE[B and $3F]; - B := B shr 6; - OutPtr.B3 := MIME_ENCODE_TABLE[B and $3F]; - B := B shr 6; - OutPtr.B2 := MIME_ENCODE_TABLE[B and $3F]; - B := B shr 6; - OutPtr.B1 := MIME_ENCODE_TABLE[B]; - Inc(OutPtr); - end; - - case InputByteCount - InMax3 of - 1: - begin - B := InPtr^; - B := B shl 4; - OutPtr.B2 := MIME_ENCODE_TABLE[B and $3F]; - B := B shr 6; - OutPtr.B1 := MIME_ENCODE_TABLE[B]; - OutPtr.B3 := EqualSign; // Fill remaining 2 bytes. - OutPtr.B4 := EqualSign; - end; - 2: - begin - B := InPtr^; - Inc(InPtr); - B := B shl 8; - B := B or InPtr^; - B := B shl 2; - OutPtr.B3 := MIME_ENCODE_TABLE[B and $3F]; - B := B shr 6; - OutPTr.b2 := MIME_ENCODE_TABLE[B and $3F]; - B := B shr 6; - OutPtr.B1 := MIME_ENCODE_TABLE[B]; - OutPtr.B4 := EqualSign; // Fill remaining byte. - end; - end; -end; - -//------------------------------------------------------------------------------ - -function MimeDecode(var InputBuffer; const InputBytesCount: Cardinal; var OutputBuffer): Cardinal; -var - ByteBuffer, ByteBufferSpace: Cardinal; -begin - ByteBuffer := 0; - ByteBufferSpace := 4; - Result := MimeDecodePartial(InputBuffer, InputBytesCount, OutputBuffer, ByteBuffer, ByteBufferSpace); - Inc(Result, MimeDecodePartialEnd(PChar(Cardinal(OutputBuffer) + Result)^, ByteBuffer, ByteBufferSpace)); -end; - -//------------------------------------------------------------------------------ - -function MimeDecodePartial(var InputBuffer; const InputBytesCount: Cardinal; - var OutputBuffer; var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal; -var - lByteBuffer, lByteBufferSpace, C: Cardinal; - InPtr, InLimitPtr: ^Byte; - OutPtr: PByte3; -begin - if InputBytesCount > 0 then - begin - InPtr := @InputBuffer; - Cardinal(InLimitPtr) := Cardinal(InPtr) + InputBytesCount; - OutPtr := @OutputBuffer; - lByteBuffer := ByteBuffer; - lByteBufferSpace := ByteBufferSpace; - while InPtr <> InLimitPtr do - begin - C := MIME_DECODE_TABLE[InPtr^]; // Read from InputBuffer. - Inc(InPtr); - if C = $FF then - Continue; - - lByteBuffer := lByteBuffer shl 6; - lByteBuffer := lByteBuffer or C; - Dec(lByteBufferSpace); - if lByteBufferSpace <> 0 then - Continue; // Read 4 bytes from InputBuffer? - - OutPtr.B3 := Byte(lByteBuffer); // Write 3 bytes to OutputBuffer (in reverse order). - lByteBuffer := lByteBuffer shr 8; - OutPtr.B2 := Byte(lByteBuffer); - lByteBuffer := lByteBuffer shr 8; - OutPtr.B1 := Byte(lByteBuffer); - lByteBuffer := 0; - Inc(OutPtr); - lByteBufferSpace := 4; - end; - ByteBuffer := lByteBuffer; - ByteBufferSpace := lByteBufferSpace; - Result := Cardinal(OutPtr) - Cardinal(@OutputBuffer); - end - else - Result := 0; -end; - -//------------------------------------------------------------------------------ - -function MimeDecodePartialEnd(var OutputBuffer; const ByteBuffer: Cardinal; - const ByteBufferSpace: Cardinal): Cardinal; -var - lByteBuffer: Cardinal; -begin - case ByteBufferSpace of - 1: - begin - lByteBuffer := ByteBuffer shr 2; - PByte3(@OutputBuffer).B2 := Byte(lByteBuffer); - lByteBuffer := lByteBuffer shr 8; - PByte3(@OutputBuffer).B1 := Byte(lByteBuffer); - Result := 2; - end; - 2: - begin - lByteBuffer := ByteBuffer shr 4; - PByte3(@OutputBuffer).B1 := Byte(lByteBuffer); - Result := 1; - end; - else - Result := 0; - end; -end; - -end. - From 96eeb95d17203acf06dbfabeabcc9af33dadece4 Mon Sep 17 00:00:00 2001 From: Philipp Winkel Date: Tue, 3 Nov 2020 17:11:34 +0100 Subject: [PATCH 5/9] XML Validation: CreateRequiredElements with correct namespaces --- Units/DelphiXMLDataBindingGenerator.pas | 12 +++++++++--- Units/DelphiXMLDataBindingResources.pas | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Units/DelphiXMLDataBindingGenerator.pas b/Units/DelphiXMLDataBindingGenerator.pas index d8ff615..2027b33 100644 --- a/Units/DelphiXMLDataBindingGenerator.pas +++ b/Units/DelphiXMLDataBindingGenerator.pas @@ -1579,7 +1579,9 @@ var elementSortCount: Integer; elementSortOrder: string; elementRequired: string; + elementNamespaceRequired: string; elementRequiredCount: Integer; + elementNamespaceRequiredCount: Integer; attributeRequired: string; attributeRequiredCount: Integer; @@ -1610,8 +1612,10 @@ begin begin case propertyItem.PropertyType of ptSimple: - AddArrayElement(elementRequired, elementRequiredCount, QuotedStr(propertyItem.Name)); - + begin + AddArrayElement(elementRequired, elementRequiredCount, QuotedStr(propertyItem.Name)); + AddArrayElement(elementNamespaceRequired, elementNamespaceRequiredCount, QuotedStr(propertyItem.TargetNamespace)); + 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 @@ -1627,8 +1631,10 @@ begin if elementRequiredCount > 0 then begin Delete(elementRequired, 1, 2); + Delete(elementNamespaceRequired, 1, 2); AWriter.WriteLineNamedFmt(IfThen(AStrict, XSDValidateStrictMethodImplementationRequired, XSDValidateMethodImplementationRequired), - ['RequiredElements', elementRequired]); + ['RequiredElements', elementRequired, + 'RequiredElementNamespaces', elementNamespaceRequired]); end; diff --git a/Units/DelphiXMLDataBindingResources.pas b/Units/DelphiXMLDataBindingResources.pas index 12fbda1..e6ea2a8 100644 --- a/Units/DelphiXMLDataBindingResources.pas +++ b/Units/DelphiXMLDataBindingResources.pas @@ -114,7 +114,7 @@ const XSDValidateMethodImplementationBegin = 'procedure TXML%:s.XSDValidate;' + CrLf + 'begin'; - XSDValidateMethodImplementationRequired = ' CreateRequiredElements(Self, [%:s]);'; + XSDValidateMethodImplementationRequired = ' CreateRequiredElements(Self, [%:s], [%:s]);'; XSDValidateMethodImplementationComplex = ' Get%:s;'; XSDValidateMethodImplementationAttrib = ' CreateRequiredAttributes(Self, [%:s]);'; XSDValidateMethodImplementationSort = ' SortChildNodes(Self, [%:s]);'; From 023c5197fedfd00ea2aa62edc3f73bec6359bdc6 Mon Sep 17 00:00:00 2001 From: Philipp Winkel Date: Tue, 10 Nov 2020 17:54:59 +0100 Subject: [PATCH 6/9] =?UTF-8?q?XML=20Kommentare=20f=C3=BCr=20Delphi=20Docu?= =?UTF-8?q?mentation=20Insight?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Units/DelphiXMLDataBindingGenerator.pas | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Units/DelphiXMLDataBindingGenerator.pas b/Units/DelphiXMLDataBindingGenerator.pas index 2027b33..17c5171 100644 --- a/Units/DelphiXMLDataBindingGenerator.pas +++ b/Units/DelphiXMLDataBindingGenerator.pas @@ -643,11 +643,11 @@ begin lines.Text := WrapText(documentation, 76); - AWriter.WriteLine(' {'); + AWriter.WriteLine(' /// '); for lineIndex := 0 to Pred(lines.Count) do - AWriter.WriteLine(' ' + lines[lineIndex]); + AWriter.WriteLine(' /// ' + lines[lineIndex]); - AWriter.WriteLine(' }'); + AWriter.WriteLine(' /// '); finally FreeAndNil(lines); end; From 9f2b2e73f644f6251405941b58855b3eb0d7eea7 Mon Sep 17 00:00:00 2001 From: Philipp Winkel Date: Mon, 1 Feb 2021 13:40:58 +0100 Subject: [PATCH 7/9] update ignore files --- .gitignore | 3 + X2XMLDataBinding.cfg | 40 ---------- X2XMLDataBinding.dof | 138 ---------------------------------- X2XMLDataBinding.res | Bin 164132 -> 0 bytes X2XMLDataBindingCmdLine.cfg | 44 ----------- X2XMLDataBindingCmdLine.dof | 144 ------------------------------------ 6 files changed, 3 insertions(+), 366 deletions(-) delete mode 100644 X2XMLDataBinding.cfg delete mode 100644 X2XMLDataBinding.dof delete mode 100644 X2XMLDataBinding.res delete mode 100644 X2XMLDataBindingCmdLine.cfg delete mode 100644 X2XMLDataBindingCmdLine.dof diff --git a/.gitignore b/.gitignore index 5a6b93f..014f670 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ bin/ lib/ __history/ +*.cfg +*.dof +*.res *.stat Docs/_build diff --git a/X2XMLDataBinding.cfg b/X2XMLDataBinding.cfg deleted file mode 100644 index 5ea2a42..0000000 --- a/X2XMLDataBinding.cfg +++ /dev/null @@ -1,40 +0,0 @@ --$A8 --$B- --$C- --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O- --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$Y+ --$Z1 --GD --cg --AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; --H+ --W+ --M --$M16384,1048576 --K$00400000 --N"lib" --LE"c:\program files\borland\delphi7\Projects\Bpl" --LN"c:\program files\borland\delphi7\Projects\Bpl" --w-UNSAFE_TYPE --w-UNSAFE_CODE --w-UNSAFE_CAST diff --git a/X2XMLDataBinding.dof b/X2XMLDataBinding.dof deleted file mode 100644 index 920fea1..0000000 --- a/X2XMLDataBinding.dof +++ /dev/null @@ -1,138 +0,0 @@ -[FileVersion] -Version=7.0 -[Compiler] -A=8 -B=0 -C=0 -D=1 -E=0 -F=0 -G=1 -H=1 -I=1 -J=0 -K=0 -L=1 -M=0 -N=1 -O=0 -P=1 -Q=0 -R=0 -S=0 -T=0 -U=0 -V=1 -W=0 -X=1 -Y=2 -Z=1 -ShowHints=1 -ShowWarnings=1 -UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -NamespacePrefix= -SymbolDeprecated=1 -SymbolLibrary=1 -SymbolPlatform=1 -UnitLibrary=1 -UnitPlatform=1 -UnitDeprecated=1 -HResultCompat=1 -HidingMember=1 -HiddenVirtual=1 -Garbage=1 -BoundsError=1 -ZeroNilCompat=1 -StringConstTruncated=1 -ForLoopVarVarPar=1 -TypedConstVarPar=1 -AsgToTypedConst=1 -CaseLabelRange=1 -ForVariable=1 -ConstructingAbstract=1 -ComparisonFalse=1 -ComparisonTrue=1 -ComparingSignedUnsigned=1 -CombiningSignedUnsigned=1 -UnsupportedConstruct=1 -FileOpen=1 -FileOpenUnitSrc=1 -BadGlobalSymbol=1 -DuplicateConstructorDestructor=1 -InvalidDirective=1 -PackageNoLink=1 -PackageThreadVar=1 -ImplicitImport=1 -HPPEMITIgnored=1 -NoRetVal=1 -UseBeforeDef=1 -ForLoopVarUndef=1 -UnitNameMismatch=1 -NoCFGFileFound=1 -MessageDirective=1 -ImplicitVariants=1 -UnicodeToLocale=1 -LocaleToUnicode=1 -ImagebaseMultiple=1 -SuspiciousTypecast=1 -PrivatePropAccessor=1 -UnsafeType=0 -UnsafeCode=0 -UnsafeCast=0 -[Linker] -MapFile=3 -OutputObjs=0 -ConsoleApp=1 -DebugInfo=0 -RemoteSymbols=0 -MinStackSize=16384 -MaxStackSize=1048576 -ImageBase=4194304 -ExeDescription= -[Directories] -OutputDir= -UnitOutputDir=lib -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages=vcl;rtl;vclx;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;dsnap;vcldb;dsnapcon;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webdsnap;websnap;adortl;CLXIB;ibxpress;VCLIB;teeui;teedb;tee;dss;vclactnband;vclshlctrls;dclOfficeXP;Indy70;cxLibraryVCLD7;dxBarD7;dxComnD7;dxBarDBNavD7;dxBarExtDBItemsD7;dxBarExtItemsD7;dxDockingD7;dxsbD7;cxEditorsVCLD7;dxThemeD7;cxDataD7;cxExtEditorsVCLD7;cxPageControlVCLD7;cxGridVCLD7;cxSchedulerVCLD7;cxTreeListVCLD7;cxVerticalGridVCLD7;cxSpreadSheetVCLD7;dxNavBarD7;cxWebD7;cxWebPascalScriptD7;cxWebSnapD7;cxWebTeeChartD7;dxMasterViewD7;dxmdsD7;dxdbtrD7;dxtrmdD7;dxorgcD7;dxdborD7;dxFlowChartD7;dxLayoutControlD7;dxLayoutControlcxEditAdaptersD7;dxPSCoreD7;dxPSTeeChartD7;dxPsPrVwAdvD7;dxPSLnksD7;dxPSdxOCLnkD7;dxPSdxMVLnkD7;dxPSdxLCLnkD7;dxPSdxFCLnkD7;dxPSdxDBTVLnkD7;dxPSdxDBOCLnkD7;dxPSDBTeeChartD7;dxPScxCommonD7;dxPScxTLLnkD7;dxPScxSSLnkD7;dxPScxPCProdD7;dxPScxGridLnkD7;dxPScxExtCommonD7;dxPScxVGridLnkD7;fo_d7;xtx_d7;Rave50CLX;Rave50VCL;pngimaged7;dxGDIPlusD7;UnRegDxPNG -Conditionals= -DebugSourceDirs= -UsePackages=0 -[Parameters] -RunParams=P:\test\DealerMap\xsd\kml21-simplified.xsd -HostApplication= -Launcher= -UseLauncher=0 -DebugCWD= -[Language] -ActiveLang= -ProjectLang= -RootDir=C:\Program Files\Borland\Delphi7\Bin\ -[Version Info] -IncludeVerInfo=0 -AutoIncBuild=0 -MajorVer=0 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1043 -CodePage=1252 -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=0.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion= -Comments= -[Excluded Packages] -C:\Program Files\Borland\Indy\D7\dclIndy70.bpl=Internet Direct (Indy) for D7 Property and Component Editors diff --git a/X2XMLDataBinding.res b/X2XMLDataBinding.res deleted file mode 100644 index c5801053e08997650fac6f3a5ff79379d59311bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164132 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/q;fV(?4B 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�HZ~6DT{yOeQ51TKDuTp-t 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 Date: Mon, 1 Feb 2021 13:51:47 +0100 Subject: [PATCH 8/9] add vendor x2utils and x2log as submodule fix search path --- .gitmodules | 6 ++++++ X2XMLDataBinding.dproj | 2 +- vendor/x2log | 1 + vendor/x2utils | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .gitmodules create mode 160000 vendor/x2log create mode 160000 vendor/x2utils diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d6dbfcf --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "vendor/x2utils"] + path = vendor/x2utils + url = https://github.com/MvRens/x2utils.git +[submodule "vendor/x2log"] + path = vendor/x2log + url = https://github.com/MvRens/x2log.git diff --git a/X2XMLDataBinding.dproj b/X2XMLDataBinding.dproj index 081bb05..3644cb8 100644 --- a/X2XMLDataBinding.dproj +++ b/X2XMLDataBinding.dproj @@ -52,7 +52,7 @@ 1043 $(BDS)\bin\default_app.manifest X2XMLDataBinding - ..\x2utils;..\x2log;$(DCC_UnitSearchPath) + vendor\x2utils;vendor\x2log;$(DCC_UnitSearchPath) Data.Win;Datasnap.Win;Web.Win;Soap.Win;Bde;$(DCC_Namespace) diff --git a/vendor/x2log b/vendor/x2log new file mode 160000 index 0000000..8b17a99 --- /dev/null +++ b/vendor/x2log @@ -0,0 +1 @@ +Subproject commit 8b17a99c33453d0cf6c94d26af735beb3bb8666c diff --git a/vendor/x2utils b/vendor/x2utils new file mode 160000 index 0000000..1e7a087 --- /dev/null +++ b/vendor/x2utils @@ -0,0 +1 @@ +Subproject commit 1e7a0873558140b506c01af5c50c73cfe940466e From 0d3ec32d5b74c2365e194e3d0d2650e5c9304605 Mon Sep 17 00:00:00 2001 From: Philipp Winkel Date: Mon, 1 Feb 2021 14:04:09 +0100 Subject: [PATCH 9/9] update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index fc35b16..0f040f8 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,10 @@ - Basic validation for outputting XML documents which applies element order for sequences and checks for the presence of required elements - Influence the generator by using a Hints file + ## Dependencies + - JEDI Component Library (jcl /jvcl) + - x2utils (https://github.com/MvRens/x2utils.git) (git submodule) + - x2log (https://github.com/MvRens/x2log.git) (git submodule) + + Documentation is available on [ReadTheDocs](https://x2xmldatabinding.readthedocs.io/). \ No newline at end of file