1
0
mirror of synced 2024-11-14 19:13:50 +00:00

Added option to check for empty elements in Has properties, as a workaround for people who don't understand the concept of optional elements or XSD's in general

This commit is contained in:
Mark van Renswoude 2017-07-21 09:38:17 +02:00
parent c16eb103da
commit e8ef5ff1bc
7 changed files with 250 additions and 87 deletions

View File

@ -4,7 +4,7 @@ object MainForm: TMainForm
BorderIcons = [biSystemMenu, biMinimize] BorderIcons = [biSystemMenu, biMinimize]
BorderStyle = bsDialog BorderStyle = bsDialog
Caption = 'X'#178'Software XML Data Binding for Delphi' Caption = 'X'#178'Software XML Data Binding for Delphi'
ClientHeight = 254 ClientHeight = 291
ClientWidth = 438 ClientWidth = 438
Color = clBtnFace Color = clBtnFace
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
@ -17,7 +17,7 @@ object MainForm: TMainForm
OnCreate = FormCreate OnCreate = FormCreate
DesignSize = ( DesignSize = (
438 438
254) 291)
PixelsPerInch = 96 PixelsPerInch = 96
TextHeight = 13 TextHeight = 13
object lblSchema: TLabel object lblSchema: TLabel
@ -44,17 +44,18 @@ object MainForm: TMainForm
Left = 8 Left = 8
Top = 43 Top = 43
Width = 422 Width = 422
Height = 167 Height = 204
Anchors = [akLeft, akTop, akBottom] Anchors = [akLeft, akTop, akBottom]
Caption = ' Output ' Caption = ' Output '
TabOrder = 1 TabOrder = 1
ExplicitHeight = 167
DesignSize = ( DesignSize = (
422 422
167) 204)
object rbFile: TRadioButton object rbFile: TRadioButton
Left = 7 Left = 11
Top = 21 Top = 21
Width = 126 Width = 127
Height = 17 Height = 17
Caption = ' Output to &single file' Caption = ' Output to &single file'
Checked = True Checked = True
@ -63,9 +64,9 @@ object MainForm: TMainForm
OnClick = OutputTypeClick OnClick = OutputTypeClick
end end
object rbFolder: TRadioButton object rbFolder: TRadioButton
Left = 8 Left = 11
Top = 44 Top = 44
Width = 149 Width = 150
Height = 17 Height = 17
Caption = ' Output to separate &files' Caption = ' Output to separate &files'
TabOrder = 1 TabOrder = 1
@ -75,15 +76,16 @@ object MainForm: TMainForm
Left = 3 Left = 3
Top = 68 Top = 68
Width = 416 Width = 416
Height = 95 Height = 93
ActivePage = spFile ActivePage = spFolder
Anchors = [akLeft, akTop, akRight, akBottom] Anchors = [akLeft, akTop, akRight]
Style = tsButtons Style = tsButtons
TabOrder = 2 TabOrder = 2
object spFile: TTabSheet object spFile: TTabSheet
TabVisible = False TabVisible = False
ExplicitHeight = 85
object lblFile: TLabel object lblFile: TLabel
Left = 8 Left = 4
Top = 7 Top = 7
Width = 55 Width = 55
Height = 13 Height = 13
@ -91,7 +93,7 @@ object MainForm: TMainForm
end end
object feFile: TcxButtonEdit object feFile: TcxButtonEdit
Left = 88 Left = 88
Top = 3 Top = 4
Properties.Buttons = < Properties.Buttons = <
item item
Kind = bkEllipsis Kind = bkEllipsis
@ -103,37 +105,35 @@ object MainForm: TMainForm
end end
object spFolder: TTabSheet object spFolder: TTabSheet
TabVisible = False TabVisible = False
ExplicitLeft = 0 ExplicitLeft = 8
ExplicitTop = 0 ExplicitHeight = 195
ExplicitWidth = 0
ExplicitHeight = 0
DesignSize = ( DesignSize = (
408 408
85) 83)
object lblFolder: TLabel object lblFolder: TLabel
Left = 8 Left = 4
Top = 7 Top = 7
Width = 69 Width = 69
Height = 13 Height = 13
Caption = 'Output folder:' Caption = 'Output folder:'
end end
object lblFolderPrefix: TLabel object lblFolderPrefix: TLabel
Left = 8 Left = 4
Top = 34 Top = 32
Width = 51 Width = 51
Height = 13 Height = 13
Caption = 'File prefix:' Caption = 'File prefix:'
end end
object lblFolderPostfix: TLabel object lblFolderPostfix: TLabel
Left = 8 Left = 4
Top = 60 Top = 58
Width = 56 Width = 56
Height = 13 Height = 13
Caption = 'File postfix:' Caption = 'File postfix:'
end end
object deFolder: TcxButtonEdit object deFolder: TcxButtonEdit
Left = 88 Left = 88
Top = 3 Top = 4
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
Properties.Buttons = < Properties.Buttons = <
item item
@ -145,23 +145,36 @@ object MainForm: TMainForm
end end
object edtFolderPrefix: TcxTextEdit object edtFolderPrefix: TcxTextEdit
Left = 88 Left = 88
Top = 30 Top = 29
TabOrder = 1 TabOrder = 1
Text = 'xml_' Text = 'xml_'
Width = 121 Width = 121
end end
object edtFolderPostfix: TcxTextEdit object edtFolderPostfix: TcxTextEdit
Left = 88 Left = 88
Top = 57 Top = 55
TabOrder = 2 TabOrder = 2
Width = 121 Width = 121
end end
end end
end end
object cbHasChecksEmpty: TCheckBox
Left = 11
Top = 175
Width = 401
Height = 17
Hint =
'Workaround for XML'#39's generated by people who do not understand t' +
'he concept of optional elements or XSD'#39's in general'
Caption =
' Check for empty elements as well as omitted elements in Has pro' +
'perties'
TabOrder = 3
end
end end
object btnGenerate: TButton object btnGenerate: TButton
Left = 274 Left = 274
Top = 221 Top = 258
Width = 75 Width = 75
Height = 25 Height = 25
Anchors = [akRight, akBottom] Anchors = [akRight, akBottom]
@ -169,10 +182,11 @@ object MainForm: TMainForm
Default = True Default = True
TabOrder = 3 TabOrder = 3
OnClick = btnGenerateClick OnClick = btnGenerateClick
ExplicitTop = 221
end end
object btnClose: TButton object btnClose: TButton
Left = 355 Left = 355
Top = 221 Top = 258
Width = 75 Width = 75
Height = 25 Height = 25
Anchors = [akRight, akBottom] Anchors = [akRight, akBottom]
@ -180,10 +194,11 @@ object MainForm: TMainForm
Caption = '&Close' Caption = '&Close'
TabOrder = 4 TabOrder = 4
OnClick = btnCloseClick OnClick = btnCloseClick
ExplicitTop = 221
end end
object btnHints: TButton object btnHints: TButton
Left = 7 Left = 7
Top = 221 Top = 258
Width = 142 Width = 142
Height = 25 Height = 25
Anchors = [akRight, akBottom] Anchors = [akRight, akBottom]
@ -191,6 +206,7 @@ object MainForm: TMainForm
Caption = 'Generate blank &Hints file' Caption = 'Generate blank &Hints file'
TabOrder = 2 TabOrder = 2
OnClick = btnHintsClick OnClick = btnHintsClick
ExplicitTop = 221
end end
object DefaultEditStyle: TcxDefaultEditStyleController object DefaultEditStyle: TcxDefaultEditStyleController
Style.HotTrack = False Style.HotTrack = False
@ -206,13 +222,13 @@ object MainForm: TMainForm
object dlgSchema: TOpenDialog object dlgSchema: TOpenDialog
Filter = 'W3C XML Schema files (*.xsd)|*.xsd|All files (*.*)|*.*' Filter = 'W3C XML Schema files (*.xsd)|*.xsd|All files (*.*)|*.*'
Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing] Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing]
Left = 260 Left = 212
Top = 156 Top = 40
end end
object dlgOutputFile: TSaveDialog object dlgOutputFile: TSaveDialog
Filter = 'Delphi source files (*.pas)|*.pas|All files (*.*)|*.*' Filter = 'Delphi source files (*.pas)|*.pas|All files (*.*)|*.*'
Options = [ofHideReadOnly, ofPathMustExist, ofEnableSizing] Options = [ofHideReadOnly, ofPathMustExist, ofEnableSizing]
Left = 343 Left = 323
Top = 157 Top = 45
end end
end end

View File

@ -51,6 +51,7 @@ type
rbFolder: TRadioButton; rbFolder: TRadioButton;
spFile: TTabSheet; spFile: TTabSheet;
spFolder: TTabSheet; spFolder: TTabSheet;
cbHasChecksEmpty: TCheckBox;
procedure btnCloseClick(Sender: TObject); procedure btnCloseClick(Sender: TObject);
procedure btnGenerateClick(Sender: TObject); procedure btnGenerateClick(Sender: TObject);
@ -181,6 +182,7 @@ begin
generator.OutputPath := deFolder.Text; generator.OutputPath := deFolder.Text;
end; end;
generator.HasChecksEmpty := cbHasChecksEmpty.Checked;
generator.OnGetFileName := GetFileName; generator.OnGetFileName := GetFileName;
generator.Execute(feSchema.Text); generator.Execute(feSchema.Text);
@ -263,14 +265,14 @@ begin
if settings.HasOutput then if settings.HasOutput then
begin begin
case settings.Output.OutputType of case settings.Output.OutputType of
OutputType_Single: DataBindingOutputType_Single:
begin begin
outputSingle := settings.Output.OutputSingle; outputSingle := settings.Output.OutputSingle;
rbFile.Checked := True; rbFile.Checked := True;
feFile.Text := outputSingle.FileName; feFile.Text := outputSingle.FileName;
end; end;
OutputType_Multiple: DataBindingOutputType_Multiple:
begin begin
outputMultiple := settings.Output.OutputMultiple; outputMultiple := settings.Output.OutputMultiple;
rbFolder.Checked := True; rbFolder.Checked := True;
@ -279,6 +281,8 @@ begin
edtFolderPostfix.Text := outputMultiple.Postfix; edtFolderPostfix.Text := outputMultiple.Postfix;
end; end;
end; end;
cbHasChecksEmpty.Checked := settings.Output.HasHasChecksEmpty and settings.Output.HasChecksEmpty;
end; end;
end; end;
end; end;
@ -302,18 +306,19 @@ begin
if rbFile.Checked then if rbFile.Checked then
begin begin
settings.Output.OutputType := OutputType_Single; settings.Output.OutputType := DataBindingOutputType_Single;
outputSingle := settings.Output.OutputSingle; outputSingle := settings.Output.OutputSingle;
outputSingle.FileName := feFile.Text; outputSingle.FileName := feFile.Text;
end else end else
begin begin
settings.Output.OutputType := OutputType_Multiple; settings.Output.OutputType := DataBindingOutputType_Multiple;
outputMultiple := settings.Output.OutputMultiple; outputMultiple := settings.Output.OutputMultiple;
outputMultiple.Path := deFolder.Text; outputMultiple.Path := deFolder.Text;
outputMultiple.Prefix := edtFolderPrefix.Text; outputMultiple.Prefix := edtFolderPrefix.Text;
outputMultiple.Postfix := edtFolderPostfix.Text; outputMultiple.Postfix := edtFolderPostfix.Text;
end; end;
settings.Output.HasChecksEmpty := cbHasChecksEmpty.Checked;
settings.OwnerDocument.SaveToFile(fileName); settings.OwnerDocument.SaveToFile(fileName);
end; end;

View File

@ -1,32 +1,35 @@
{ {
X2Software XML Data Binding X2Software XML Data Binding
Generated on: 24-4-2008 11:37:27 Generated on: 21-7-2017 9:19:46
Generated from: P:\test\XMLDataBinding\XSD\DataBindingSettings.xsd Generated from: P:\x2xmldatabinding\XSD\DataBindingSettings.xsd
} }
unit DataBindingSettingsXML; unit DataBindingSettingsXML;
interface interface
uses uses
Classes, Classes,
SysUtils,
XMLDoc, XMLDoc,
XMLIntf; XMLIntf,
XMLDataBindingUtils;
type type
{ Forward declarations for DataBindingSettings } { Forward declarations for DataBindingSettings }
IXMLDataBindingSettings = interface; IXMLDataBindingSettings = interface;
IXMLDataBindingOutput = interface; IXMLDataBindingOutput = interface;
TXMLOutputType = (OutputType_Single,
OutputType_Multiple);
IXMLOutputSingle = interface; IXMLOutputSingle = interface;
IXMLOutputMultiple = interface; IXMLOutputMultiple = interface;
TXMLDataBindingOutputType = (DataBindingOutputType_Single,
DataBindingOutputType_Multiple);
{ Interfaces for DataBindingSettings } { Interfaces for DataBindingSettings }
{ {
Contains the settings and hints for the Delphi XML Data Binding. Contains the settings and hints for the Delphi XML Data Binding.
} }
IXMLDataBindingSettings = interface(IXMLNode) IXMLDataBindingSettings = interface(IXMLNode)
['{C78D63A5-77C2-4547-AC37-5311160D543B}'] ['{0407CBCB-B49B-4ED3-A2F6-CCDDFE46F334}']
procedure XSDValidateDocument(AStrict: Boolean = False);
function GetHasOutput: Boolean; function GetHasOutput: Boolean;
function GetOutput: IXMLDataBindingOutput; function GetOutput: IXMLDataBindingOutput;
@ -38,27 +41,38 @@ type
Contains the user-defined output settings last used Contains the user-defined output settings last used
} }
IXMLDataBindingOutput = interface(IXMLNode) IXMLDataBindingOutput = interface(IXMLNode)
['{81374819-83EF-42A8-A7B8-2F59A470D77B}'] ['{21821EFA-C7D8-4299-BF44-8122FBF2BC2E}']
procedure XSDValidate;
procedure XSDValidateStrict(AResult: IXSDValidateStrictResult);
function GetOutputTypeText: WideString; function GetOutputTypeText: WideString;
function GetOutputType: TXMLOutputType; function GetOutputType: TXMLDataBindingOutputType;
function GetHasOutputSingle: Boolean; function GetHasOutputSingle: Boolean;
function GetOutputSingle: IXMLOutputSingle; function GetOutputSingle: IXMLOutputSingle;
function GetHasOutputMultiple: Boolean; function GetHasOutputMultiple: Boolean;
function GetOutputMultiple: IXMLOutputMultiple; function GetOutputMultiple: IXMLOutputMultiple;
function GetHasHasChecksEmpty: Boolean;
function GetHasChecksEmpty: Boolean;
procedure SetOutputTypeText(const Value: WideString); procedure SetOutputTypeText(const Value: WideString);
procedure SetOutputType(const Value: TXMLOutputType); procedure SetOutputType(const Value: TXMLDataBindingOutputType);
procedure SetHasChecksEmpty(const Value: Boolean);
property OutputTypeText: WideString read GetOutputTypeText write SetOutputTypeText; property OutputTypeText: WideString read GetOutputTypeText write SetOutputTypeText;
property OutputType: TXMLOutputType read GetOutputType write SetOutputType; property OutputType: TXMLDataBindingOutputType read GetOutputType write SetOutputType;
property HasOutputSingle: Boolean read GetHasOutputSingle; property HasOutputSingle: Boolean read GetHasOutputSingle;
property OutputSingle: IXMLOutputSingle read GetOutputSingle; property OutputSingle: IXMLOutputSingle read GetOutputSingle;
property HasOutputMultiple: Boolean read GetHasOutputMultiple; property HasOutputMultiple: Boolean read GetHasOutputMultiple;
property OutputMultiple: IXMLOutputMultiple read GetOutputMultiple; property OutputMultiple: IXMLOutputMultiple read GetOutputMultiple;
property HasHasChecksEmpty: Boolean read GetHasHasChecksEmpty;
property HasChecksEmpty: Boolean read GetHasChecksEmpty write SetHasChecksEmpty;
end; end;
IXMLOutputSingle = interface(IXMLNode) IXMLOutputSingle = interface(IXMLNode)
['{9BB52722-C7C0-45F8-81A1-59BE074BF62E}'] ['{ABB2D62A-0B4D-4E4B-8835-ED8AFE7564EA}']
procedure XSDValidate;
procedure XSDValidateStrict(AResult: IXSDValidateStrictResult);
function GetFileName: WideString; function GetFileName: WideString;
procedure SetFileName(const Value: WideString); procedure SetFileName(const Value: WideString);
@ -67,7 +81,10 @@ type
end; end;
IXMLOutputMultiple = interface(IXMLNode) IXMLOutputMultiple = interface(IXMLNode)
['{4B5AC82E-572A-4C21-B779-4626BF79E0E6}'] ['{2F4918D6-EE9C-4986-9052-285A8B4D58C5}']
procedure XSDValidate;
procedure XSDValidateStrict(AResult: IXSDValidateStrictResult);
function GetPath: WideString; function GetPath: WideString;
function GetPrefix: WideString; function GetPrefix: WideString;
function GetPostfix: WideString; function GetPostfix: WideString;
@ -83,38 +100,51 @@ type
{ Classes for DataBindingSettings } { Classes for DataBindingSettings }
TXMLDataBindingSettings = class(TXMLNode, IXMLDataBindingSettings) TXMLDataBindingSettings = class(TX2XMLNode, IXMLDataBindingSettings)
public public
procedure AfterConstruction; override; procedure AfterConstruction; override;
protected protected
procedure XSDValidateDocument(AStrict: Boolean = False);
function GetHasOutput: Boolean; function GetHasOutput: Boolean;
function GetOutput: IXMLDataBindingOutput; function GetOutput: IXMLDataBindingOutput;
end; end;
TXMLDataBindingOutput = class(TXMLNode, IXMLDataBindingOutput) TXMLDataBindingOutput = class(TX2XMLNode, IXSDValidate, IXSDValidateStrict, IXMLDataBindingOutput)
public public
procedure AfterConstruction; override; procedure AfterConstruction; override;
protected protected
procedure XSDValidate;
procedure XSDValidateStrict(AResult: IXSDValidateStrictResult);
function GetOutputTypeText: WideString; function GetOutputTypeText: WideString;
function GetOutputType: TXMLOutputType; function GetOutputType: TXMLDataBindingOutputType;
function GetHasOutputSingle: Boolean; function GetHasOutputSingle: Boolean;
function GetOutputSingle: IXMLOutputSingle; function GetOutputSingle: IXMLOutputSingle;
function GetHasOutputMultiple: Boolean; function GetHasOutputMultiple: Boolean;
function GetOutputMultiple: IXMLOutputMultiple; function GetOutputMultiple: IXMLOutputMultiple;
function GetHasHasChecksEmpty: Boolean;
function GetHasChecksEmpty: Boolean;
procedure SetOutputTypeText(const Value: WideString); procedure SetOutputTypeText(const Value: WideString);
procedure SetOutputType(const Value: TXMLOutputType); procedure SetOutputType(const Value: TXMLDataBindingOutputType);
procedure SetHasChecksEmpty(const Value: Boolean);
end; end;
TXMLOutputSingle = class(TXMLNode, IXMLOutputSingle) TXMLOutputSingle = class(TX2XMLNode, IXSDValidate, IXSDValidateStrict, IXMLOutputSingle)
protected protected
procedure XSDValidate;
procedure XSDValidateStrict(AResult: IXSDValidateStrictResult);
function GetFileName: WideString; function GetFileName: WideString;
procedure SetFileName(const Value: WideString); procedure SetFileName(const Value: WideString);
end; end;
TXMLOutputMultiple = class(TXMLNode, IXMLOutputMultiple) TXMLOutputMultiple = class(TX2XMLNode, IXSDValidate, IXSDValidateStrict, IXMLOutputMultiple)
protected protected
procedure XSDValidate;
procedure XSDValidateStrict(AResult: IXSDValidateStrictResult);
function GetPath: WideString; function GetPath: WideString;
function GetPrefix: WideString; function GetPrefix: WideString;
function GetPostfix: WideString; function GetPostfix: WideString;
@ -126,9 +156,10 @@ type
{ Document functions } { Document functions }
function GetDataBindingSettings(ADocument: IXMLDocument): IXMLDataBindingSettings; function GetDataBindingSettings(ADocument: XMLIntf.IXMLDocument): IXMLDataBindingSettings;
function LoadDataBindingSettings(const AFileName: String): IXMLDataBindingSettings; function LoadDataBindingSettings(const AFileName: String): IXMLDataBindingSettings;
function LoadDataBindingSettingsFromStream(AStream: TStream): IXMLDataBindingSettings; function LoadDataBindingSettingsFromStream(AStream: TStream): IXMLDataBindingSettings;
function LoadDataBindingSettingsFromString(const AString: String{$IF CompilerVersion >= 20}; AEncoding: TEncoding = nil; AOwnsEncoding: Boolean = True{$IFEND}): IXMLDataBindingSettings;
function NewDataBindingSettings: IXMLDataBindingSettings; function NewDataBindingSettings: IXMLDataBindingSettings;
@ -137,21 +168,21 @@ const
const const
OutputTypeValues: array[TXMLOutputType] of WideString = DataBindingOutputTypeValues: array[TXMLDataBindingOutputType] of WideString =
( (
'Single', 'Single',
'Multiple' 'Multiple'
); );
{ Enumeration conversion helpers } { Enumeration conversion helpers }
function StringToOutputType(const AValue: WideString): TXMLOutputType; function StringToDataBindingOutputType(const AValue: WideString): TXMLDataBindingOutputType;
implementation implementation
uses uses
SysUtils; Variants;
{ Document functions } { Document functions }
function GetDataBindingSettings(ADocument: IXMLDocument): IXMLDataBindingSettings; function GetDataBindingSettings(ADocument: XMLIntf.IXMLDocument): IXMLDataBindingSettings;
begin begin
Result := ADocument.GetDocBinding('DataBindingSettings', TXMLDataBindingSettings, TargetNamespace) as IXMLDataBindingSettings Result := ADocument.GetDocBinding('DataBindingSettings', TXMLDataBindingSettings, TargetNamespace) as IXMLDataBindingSettings
end; end;
@ -163,7 +194,7 @@ end;
function LoadDataBindingSettingsFromStream(AStream: TStream): IXMLDataBindingSettings; function LoadDataBindingSettingsFromStream(AStream: TStream): IXMLDataBindingSettings;
var var
doc: IXMLDocument; doc: XMLIntf.IXMLDocument;
begin begin
doc := NewXMLDocument; doc := NewXMLDocument;
@ -171,6 +202,24 @@ begin
Result := GetDataBindingSettings(doc); Result := GetDataBindingSettings(doc);
end; end;
function LoadDataBindingSettingsFromString(const AString: String{$IF CompilerVersion >= 20}; AEncoding: TEncoding; AOwnsEncoding: Boolean{$IFEND}): IXMLDataBindingSettings;
var
stream: TStringStream;
begin
{$IF CompilerVersion >= 20}
if Assigned(AEncoding) then
stream := TStringStream.Create(AString, AEncoding, AOwnsEncoding)
else
{$IFEND}
stream := TStringStream.Create(AString);
try
Result := LoadDataBindingSettingsFromStream(stream);
finally
FreeAndNil(stream);
end;
end;
function NewDataBindingSettings: IXMLDataBindingSettings; function NewDataBindingSettings: IXMLDataBindingSettings;
begin begin
Result := NewXMLDocument.GetDocBinding('DataBindingSettings', TXMLDataBindingSettings, TargetNamespace) as IXMLDataBindingSettings Result := NewXMLDocument.GetDocBinding('DataBindingSettings', TXMLDataBindingSettings, TargetNamespace) as IXMLDataBindingSettings
@ -179,14 +228,14 @@ end;
{ Enumeration conversion helpers } { Enumeration conversion helpers }
function StringToOutputType(const AValue: WideString): TXMLOutputType; function StringToDataBindingOutputType(const AValue: WideString): TXMLDataBindingOutputType;
var var
enumValue: TXMLOutputType; enumValue: TXMLDataBindingOutputType;
begin begin
Result := TXMLOutputType(-1); Result := TXMLDataBindingOutputType(-1);
for enumValue := Low(TXMLOutputType) to High(TXMLOutputType) do for enumValue := Low(TXMLDataBindingOutputType) to High(TXMLDataBindingOutputType) do
if OutputTypeValues[enumValue] = AValue then if DataBindingOutputTypeValues[enumValue] = AValue then
begin begin
Result := enumValue; Result := enumValue;
break; break;
@ -201,6 +250,14 @@ begin
inherited; inherited;
end; end;
procedure TXMLDataBindingSettings.XSDValidateDocument(AStrict: Boolean);
begin
if AStrict then
XMLDataBindingUtils.XSDValidateStrict(Self)
else
XMLDataBindingUtils.XSDValidate(Self);
end;
function TXMLDataBindingSettings.GetHasOutput: Boolean; function TXMLDataBindingSettings.GetHasOutput: Boolean;
begin begin
Result := Assigned(ChildNodes.FindNode('Output')); Result := Assigned(ChildNodes.FindNode('Output'));
@ -219,15 +276,27 @@ begin
inherited; inherited;
end; end;
procedure TXMLDataBindingOutput.XSDValidate;
begin
GetOutputType;
SortChildNodes(Self, ['OutputType', 'OutputSingle', 'OutputMultiple', 'HasChecksEmpty']);
end;
procedure TXMLDataBindingOutput.XSDValidateStrict(AResult: IXSDValidateStrictResult);
begin
GetOutputType;
SortChildNodes(Self, ['OutputType', 'OutputSingle', 'OutputMultiple', 'HasChecksEmpty']);
end;
function TXMLDataBindingOutput.GetOutputTypeText: WideString; function TXMLDataBindingOutput.GetOutputTypeText: WideString;
begin begin
Result := ChildNodes['OutputType'].Text; Result := ChildNodes['OutputType'].Text;
end; end;
function TXMLDataBindingOutput.GetOutputType: TXMLOutputType; function TXMLDataBindingOutput.GetOutputType: TXMLDataBindingOutputType;
begin begin
Result := StringToOutputType(GetOutputTypeText); Result := StringToDataBindingOutputType(GetOutputTypeText);
end; end;
function TXMLDataBindingOutput.GetHasOutputSingle: Boolean; function TXMLDataBindingOutput.GetHasOutputSingle: Boolean;
@ -252,15 +321,41 @@ begin
Result := (ChildNodes['OutputMultiple'] as IXMLOutputMultiple); Result := (ChildNodes['OutputMultiple'] as IXMLOutputMultiple);
end; end;
function TXMLDataBindingOutput.GetHasHasChecksEmpty: Boolean;
begin
Result := Assigned(ChildNodes.FindNode('HasChecksEmpty'));
end;
function TXMLDataBindingOutput.GetHasChecksEmpty: Boolean;
begin
Result := ChildNodes['HasChecksEmpty'].NodeValue;
end;
procedure TXMLDataBindingOutput.SetOutputTypeText(const Value: WideString); procedure TXMLDataBindingOutput.SetOutputTypeText(const Value: WideString);
begin begin
ChildNodes['OutputType'].NodeValue := Value; ChildNodes['OutputType'].NodeValue := Value;
end; end;
procedure TXMLDataBindingOutput.SetOutputType(const Value: TXMLOutputType); procedure TXMLDataBindingOutput.SetOutputType(const Value: TXMLDataBindingOutputType);
begin begin
ChildNodes['OutputType'].NodeValue := OutputTypeValues[Value]; ChildNodes['OutputType'].NodeValue := DataBindingOutputTypeValues[Value];
end;
procedure TXMLDataBindingOutput.SetHasChecksEmpty(const Value: Boolean);
begin
ChildNodes['HasChecksEmpty'].NodeValue := BoolToXML(Value);
end;
procedure TXMLOutputSingle.XSDValidate;
begin
CreateRequiredElements(Self, ['FileName']);
end;
procedure TXMLOutputSingle.XSDValidateStrict(AResult: IXSDValidateStrictResult);
begin
ValidateRequiredElements(AResult, Self, ['FileName']);
end; end;
function TXMLOutputSingle.GetFileName: WideString; function TXMLOutputSingle.GetFileName: WideString;
@ -270,7 +365,19 @@ end;
procedure TXMLOutputSingle.SetFileName(const Value: WideString); procedure TXMLOutputSingle.SetFileName(const Value: WideString);
begin begin
ChildNodes['FileName'].NodeValue := Value; ChildNodes['FileName'].NodeValue := GetValidXMLText(Value);
end;
procedure TXMLOutputMultiple.XSDValidate;
begin
CreateRequiredElements(Self, ['Path', 'Prefix', 'Postfix']);
SortChildNodes(Self, ['Path', 'Prefix', 'Postfix']);
end;
procedure TXMLOutputMultiple.XSDValidateStrict(AResult: IXSDValidateStrictResult);
begin
ValidateRequiredElements(AResult, Self, ['Path', 'Prefix', 'Postfix']);
SortChildNodes(Self, ['Path', 'Prefix', 'Postfix']);
end; end;
function TXMLOutputMultiple.GetPath: WideString; function TXMLOutputMultiple.GetPath: WideString;
@ -290,17 +397,17 @@ end;
procedure TXMLOutputMultiple.SetPath(const Value: WideString); procedure TXMLOutputMultiple.SetPath(const Value: WideString);
begin begin
ChildNodes['Path'].NodeValue := Value; ChildNodes['Path'].NodeValue := GetValidXMLText(Value);
end; end;
procedure TXMLOutputMultiple.SetPrefix(const Value: WideString); procedure TXMLOutputMultiple.SetPrefix(const Value: WideString);
begin begin
ChildNodes['Prefix'].NodeValue := Value; ChildNodes['Prefix'].NodeValue := GetValidXMLText(Value);
end; end;
procedure TXMLOutputMultiple.SetPostfix(const Value: WideString); procedure TXMLOutputMultiple.SetPostfix(const Value: WideString);
begin begin
ChildNodes['Postfix'].NodeValue := Value; ChildNodes['Postfix'].NodeValue := GetValidXMLText(Value);
end; end;

View File

@ -21,6 +21,7 @@ type
FProcessedItems: TList<TXMLDataBindingInterface>; FProcessedItems: TList<TXMLDataBindingInterface>;
FUnitNames: TDictionary<TXMLDataBindingSchema, String>; FUnitNames: TDictionary<TXMLDataBindingSchema, String>;
FHasChecksEmpty: Boolean;
FOnGetFileName: TGetFileNameEvent; FOnGetFileName: TGetFileNameEvent;
protected protected
procedure GenerateDataBinding; override; procedure GenerateDataBinding; override;
@ -70,6 +71,8 @@ type
property ProcessedItems: TList<TXMLDataBindingInterface> read FProcessedItems; property ProcessedItems: TList<TXMLDataBindingInterface> read FProcessedItems;
property UnitNames: TDictionary<TXMLDataBindingSchema, String> read FUnitNames; property UnitNames: TDictionary<TXMLDataBindingSchema, String> read FUnitNames;
public public
property HasChecksEmpty: Boolean read FHasChecksEmpty write FHasChecksEmpty;
property OnGetFileName: TGetFileNameEvent read FOnGetFileName write FOnGetFileName; property OnGetFileName: TGetFileNameEvent read FOnGetFileName write FOnGetFileName;
end; end;
@ -1141,6 +1144,7 @@ var
writeStream: Boolean; writeStream: Boolean;
typeMapping: TTypeMapping; typeMapping: TTypeMapping;
nodeType: TDelphiNodeType; nodeType: TDelphiNodeType;
elementType: TDelphiElementType;
begin begin
Result := False; Result := False;
@ -1295,9 +1299,12 @@ begin
if writeOptional then if writeOptional then
if AProperty.IsAttribute then if AProperty.IsAttribute then
sourceCode.Add(PropertyImplMethodGetOptionalAttr) sourceCode.Add(IfThen(HasChecksEmpty, PropertyImplMethodGetOptionalAttrEmpty, PropertyImplMethodGetOptionalAttr))
else else
sourceCode.Add(PropertyImplMethodGetOptional[GetDelphiElementType(nodeType)]); begin
elementType := GetDelphiElementType(nodeType);
sourceCode.Add(IfThen(HasChecksEmpty, PropertyImplMethodGetOptionalEmpty[elementType], PropertyImplMethodGetOptional[elementType]));
end;
if writeNil then if writeNil then
sourceCode.Add(PropertyImplMethodGetNil[GetDelphiElementType(nodeType)]); sourceCode.Add(PropertyImplMethodGetNil[GetDelphiElementType(nodeType)]);

View File

@ -198,6 +198,31 @@ const
'end;' + CrLf + 'end;' + CrLf +
'' + CrLf; '' + CrLf;
PropertyImplMethodGetOptionalEmpty: array[TDelphiElementType] of string =
(
{ dntElement }
'function TXML%<Name>:s.GetHas%<PropertyName>:s: Boolean;' + CrLf +
'begin' + CrLf +
' Result := Assigned(ChildNodes.FindNode(''%<PropertySourceName>:s'')) and (Length(ChildNodes[''%<PropertySourceName>:s''].Text) > 0);' + CrLf +
'end;' + CrLf +
'' + CrLf,
{ dntElementNS }
'function TXML%<Name>:s.GetHas%<PropertyName>:s: Boolean;' + CrLf +
'begin' + CrLf +
' Result := Assigned(ChildNodes.FindNode(''%<PropertySourceName>:s'', ''%<Namespace>:s'')) and (Length(ChildNodesNS[''%<PropertySourceName>:s'', ''%<Namespace>:s''].Text) > 0);' + CrLf +
'end;' + CrLf +
'' + CrLf
);
PropertyImplMethodGetOptionalAttrEmpty = 'function TXML%<Name>:s.GetHas%<PropertyName>:s: Boolean;' + CrLf +
'begin' + CrLf +
' Result := Assigned(AttributeNodes.FindNode(''%<PropertySourceName>:s'')) and (Length(AttributeNodes[''%<PropertySourceName>:s''].Text) > 0);' + CrLf +
'end;' + CrLf +
'' + CrLf;
PropertyImplMethodGetNil: array[TDelphiElementType] of string = PropertyImplMethodGetNil: array[TDelphiElementType] of string =
( (
{ dntElement } { dntElement }

View File

@ -0,0 +1,2 @@
<?xml version="1.0"?>
<DataBindingSettings xmlns="http://www.x2software.net/xsd/databinding/DataBindingSettings.xsd"><Output><OutputType>Single</OutputType><OutputSingle><FileName>..\Units\DataBindingSettingsXML.pas</FileName></OutputSingle></Output></DataBindingSettings>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.x2software.net/xsd/databinding/DataBindingSettings.xsd" xmlns:tns="http://www.x2software.net/xsd/databinding/DataBindingSettings.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:schema xmlns:tns="http://www.x2software.net/xsd/databinding/DataBindingSettings.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.x2software.net/xsd/databinding/DataBindingSettings.xsd" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="DataBindingSettings"> <xs:element name="DataBindingSettings">
<xs:annotation> <xs:annotation>
<xs:documentation>Contains the settings and hints for the Delphi XML Data Binding.</xs:documentation> <xs:documentation>Contains the settings and hints for the Delphi XML Data Binding.</xs:documentation>
@ -34,6 +34,7 @@
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
</xs:choice> </xs:choice>
<xs:element name="HasChecksEmpty" type="xs:boolean" minOccurs="0"/>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
<xs:simpleType name="DataBindingOutputType"> <xs:simpleType name="DataBindingOutputType">