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