* Renamed TDOMParseOptions to TXMLReaderSettings (TDOMParseOptions left as alias).

- ResolveExternals option removed, it never actually worked and its functionality should be implemented by means of OnResolveEntity event.
* Moved OnError handler from TDOMParser to TXMLReaderSettings, TDOMParser.OnError redirected to set Options.OnError.
* TDOMParser replaced by TXMLReaderSettings in parameters of TXMLTextReader constructors.

git-svn-id: trunk@20708 -
This commit is contained in:
sergei 2012-04-05 13:38:32 +00:00
parent 9867f34398
commit cc3023d55d

View File

@ -57,18 +57,20 @@ procedure ReadDTDFile(out ADoc: TXMLDocument; f: TStream); overload;
procedure ReadDTDFile(out ADoc: TXMLDocument; f: TStream; const ABaseURI: String); overload; procedure ReadDTDFile(out ADoc: TXMLDocument; f: TStream; const ABaseURI: String); overload;
type type
TDOMParseOptions = class(TObject) TXMLErrorEvent = procedure(Error: EXMLReadError) of object;
TXMLReaderSettings = class(TObject)
private private
FValidate: Boolean; FValidate: Boolean;
FPreserveWhitespace: Boolean; FPreserveWhitespace: Boolean;
FExpandEntities: Boolean; FExpandEntities: Boolean;
FIgnoreComments: Boolean; FIgnoreComments: Boolean;
FCDSectionsAsText: Boolean; FCDSectionsAsText: Boolean;
FResolveExternals: Boolean;
FNamespaces: Boolean; FNamespaces: Boolean;
FDisallowDoctype: Boolean; FDisallowDoctype: Boolean;
FCanonical: Boolean; FCanonical: Boolean;
FMaxChars: Cardinal; FMaxChars: Cardinal;
FOnError: TXMLErrorEvent;
function GetCanonical: Boolean; function GetCanonical: Boolean;
procedure SetCanonical(aValue: Boolean); procedure SetCanonical(aValue: Boolean);
public public
@ -77,13 +79,15 @@ type
property ExpandEntities: Boolean read FExpandEntities write FExpandEntities; property ExpandEntities: Boolean read FExpandEntities write FExpandEntities;
property IgnoreComments: Boolean read FIgnoreComments write FIgnoreComments; property IgnoreComments: Boolean read FIgnoreComments write FIgnoreComments;
property CDSectionsAsText: Boolean read FCDSectionsAsText write FCDSectionsAsText; property CDSectionsAsText: Boolean read FCDSectionsAsText write FCDSectionsAsText;
property ResolveExternals: Boolean read FResolveExternals write FResolveExternals;
property Namespaces: Boolean read FNamespaces write FNamespaces; property Namespaces: Boolean read FNamespaces write FNamespaces;
property DisallowDoctype: Boolean read FDisallowDoctype write FDisallowDoctype; property DisallowDoctype: Boolean read FDisallowDoctype write FDisallowDoctype;
property MaxChars: Cardinal read FMaxChars write FMaxChars; property MaxChars: Cardinal read FMaxChars write FMaxChars;
property CanonicalForm: Boolean read GetCanonical write SetCanonical; property CanonicalForm: Boolean read GetCanonical write SetCanonical;
property OnError: TXMLErrorEvent read FOnError write FOnError;
end; end;
TDOMParseOptions = TXMLReaderSettings;
// NOTE: DOM 3 LS ACTION_TYPE enumeration starts at 1 // NOTE: DOM 3 LS ACTION_TYPE enumeration starts at 1
TXMLContextAction = ( TXMLContextAction = (
xaAppendAsChildren = 1, xaAppendAsChildren = 1,
@ -92,8 +96,6 @@ type
xaInsertAfter, xaInsertAfter,
xaReplace); xaReplace);
TXMLErrorEvent = procedure(Error: EXMLReadError) of object;
TXMLInputSource = class(TObject) TXMLInputSource = class(TObject)
private private
FStream: TStream; FStream: TStream;
@ -116,7 +118,8 @@ type
TDOMParser = class(TObject) TDOMParser = class(TObject)
private private
FOptions: TDOMParseOptions; FOptions: TDOMParseOptions;
FOnError: TXMLErrorEvent; function GetOnError: TXMLErrorEvent;
procedure SetOnError(value: TXMLErrorEvent);
public public
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
@ -125,7 +128,7 @@ type
function ParseWithContext(Src: TXMLInputSource; Context: TDOMNode; function ParseWithContext(Src: TXMLInputSource; Context: TDOMNode;
Action: TXMLContextAction): TDOMNode; Action: TXMLContextAction): TDOMNode;
property Options: TDOMParseOptions read FOptions; property Options: TDOMParseOptions read FOptions;
property OnError: TXMLErrorEvent read FOnError write FOnError; property OnError: TXMLErrorEvent read GetOnError write SetOnError;
end; end;
TDecoder = record TDecoder = record
@ -274,7 +277,6 @@ type
private private
FSource: TXMLCharSource; FSource: TXMLCharSource;
FNameTable: THashTable; FNameTable: THashTable;
FCtrl: TDOMParser;
FXML11: Boolean; FXML11: Boolean;
FNameTableOwned: Boolean; FNameTableOwned: Boolean;
FState: TXMLReadState; FState: TXMLReadState;
@ -311,11 +313,11 @@ type
FExpandEntities: Boolean; FExpandEntities: Boolean;
FIgnoreComments: Boolean; FIgnoreComments: Boolean;
FCDSectionsAsText: Boolean; FCDSectionsAsText: Boolean;
FResolveExternals: Boolean;
FNamespaces: Boolean; FNamespaces: Boolean;
FDisallowDoctype: Boolean; FDisallowDoctype: Boolean;
FCanonical: Boolean; FCanonical: Boolean;
FMaxChars: Cardinal; FMaxChars: Cardinal;
FOnError: TXMLErrorEvent;
FCurrAttrIndex: Integer; FCurrAttrIndex: Integer;
FOnEntity: TEntityEvent; FOnEntity: TEntityEvent;
@ -456,15 +458,14 @@ type
procedure ValidationErrorWithName(const Msg: string; LineOffs: Integer = -1); procedure ValidationErrorWithName(const Msg: string; LineOffs: Integer = -1);
procedure DTDReloadHook; procedure DTDReloadHook;
procedure ConvertSource(SrcIn: TXMLInputSource; out SrcOut: TXMLCharSource); procedure ConvertSource(SrcIn: TXMLInputSource; out SrcOut: TXMLCharSource);
procedure SetOptions(AParser: TDOMParser); procedure SetOptions(AValue: TXMLReaderSettings);
procedure SetNametable(ANameTable: THashTable); procedure SetNametable(ANameTable: THashTable);
public public
constructor Create; overload;
constructor Create(var AFile: Text; ANameTable: THashTable); overload; constructor Create(var AFile: Text; ANameTable: THashTable); overload;
constructor Create(AStream: TStream; const ABaseUri: XMLString; ANameTable: THashTable); overload; constructor Create(AStream: TStream; const ABaseUri: XMLString; ANameTable: THashTable); overload;
constructor Create(ASrc: TXMLCharSource; AParent: TXMLTextReader); overload; constructor Create(ASrc: TXMLCharSource; AParent: TXMLTextReader); overload;
constructor Create(const uri: XMLString; ANameTable: THashTable; AParser: TDOMParser); overload; constructor Create(const uri: XMLString; ANameTable: THashTable; ASettings: TXMLReaderSettings); overload;
constructor Create(ASrc: TXMLInputSource; ANameTable: THashTable; AParser: TDOMParser); overload; constructor Create(ASrc: TXMLInputSource; ANameTable: THashTable; ASettings: TXMLReaderSettings); overload;
destructor Destroy; override; destructor Destroy; override;
procedure AfterConstruction; override; procedure AfterConstruction; override;
property OnEntity: TEntityEvent read FOnEntity write FOnEntity; property OnEntity: TEntityEvent read FOnEntity write FOnEntity;
@ -530,16 +531,16 @@ begin
end; end;
{ TDOMParseOptions } { TXMLReaderSettings }
function TDOMParseOptions.GetCanonical: Boolean; function TXMLReaderSettings.GetCanonical: Boolean;
begin begin
Result := FCanonical and FExpandEntities and FCDSectionsAsText and Result := FCanonical and FExpandEntities and FCDSectionsAsText and
{ (not normalizeCharacters) and } FNamespaces and { (not normalizeCharacters) and } FNamespaces and
{ namespaceDeclarations and } FPreserveWhitespace; { namespaceDeclarations and } FPreserveWhitespace;
end; end;
procedure TDOMParseOptions.SetCanonical(aValue: Boolean); procedure TXMLReaderSettings.SetCanonical(aValue: Boolean);
begin begin
FCanonical := aValue; FCanonical := aValue;
if aValue then if aValue then
@ -581,13 +582,23 @@ begin
inherited Destroy; inherited Destroy;
end; end;
function TDOMParser.GetOnError: TXMLErrorEvent;
begin
result := Options.OnError;
end;
procedure TDOMParser.SetOnError(value: TXMLErrorEvent);
begin
Options.OnError := value;
end;
procedure TDOMParser.Parse(Src: TXMLInputSource; out ADoc: TXMLDocument); procedure TDOMParser.Parse(Src: TXMLInputSource; out ADoc: TXMLDocument);
var var
Reader: TXMLTextReader; Reader: TXMLTextReader;
ldr: TLoader; ldr: TLoader;
begin begin
ADoc := TXMLDocument.Create; ADoc := TXMLDocument.Create;
Reader := TXMLTextReader.Create(Src, ADoc.Names, Self); Reader := TXMLTextReader.Create(Src, ADoc.Names, Options);
try try
ldr.ProcessXML(ADoc, Reader); ldr.ProcessXML(ADoc, Reader);
finally finally
@ -601,7 +612,7 @@ var
ldr: TLoader; ldr: TLoader;
begin begin
ADoc := TXMLDocument.Create; ADoc := TXMLDocument.Create;
Reader := TXMLTextReader.Create(URI, ADoc.Names, Self); Reader := TXMLTextReader.Create(URI, ADoc.Names, Options);
try try
ldr.ProcessXML(ADoc, Reader) ldr.ProcessXML(ADoc, Reader)
finally finally
@ -628,7 +639,7 @@ begin
if not (node.NodeType in [ELEMENT_NODE, DOCUMENT_FRAGMENT_NODE]) then if not (node.NodeType in [ELEMENT_NODE, DOCUMENT_FRAGMENT_NODE]) then
raise EDOMHierarchyRequest.Create('DOMParser.ParseWithContext'); raise EDOMHierarchyRequest.Create('DOMParser.ParseWithContext');
reader := TXMLTextReader.Create(Src, Context.OwnerDocument.Names, Self); reader := TXMLTextReader.Create(Src, Context.OwnerDocument.Names, Options);
try try
Frag := Context.OwnerDocument.CreateDocumentFragment; Frag := Context.OwnerDocument.CreateDocumentFragment;
try try
@ -1180,8 +1191,8 @@ end;
procedure TXMLTextReader.CallErrorHandler(E: EXMLReadError); procedure TXMLTextReader.CallErrorHandler(E: EXMLReadError);
begin begin
try try
if Assigned(FCtrl) and Assigned(FCtrl.FOnError) then if Assigned(FOnError) then
FCtrl.FOnError(E); FOnError(E);
if E.Severity = esFatal then if E.Severity = esFatal then
raise E; raise E;
except except
@ -1297,49 +1308,36 @@ end;
const const
PrefixDefault: array[0..4] of WideChar = ('x','m','l','n','s'); PrefixDefault: array[0..4] of WideChar = ('x','m','l','n','s');
constructor TXMLTextReader.Create; procedure TXMLTextReader.SetOptions(AValue: TXMLReaderSettings);
begin begin
inherited Create; FValidate := AValue.Validate;
BufAllocate(FName, 128); FPreserveWhitespace := AValue.PreserveWhitespace;
BufAllocate(FValue, 512); FExpandEntities := AValue.ExpandEntities;
FCDSectionsAsText := AValue.CDSectionsAsText;
SetLength(FNodeStack, 16); FIgnoreComments := AValue.IgnoreComments;
SetLength(FValidators, 16); FNamespaces := AValue.Namespaces;
FDisallowDoctype := AValue.DisallowDoctype;
FCanonical := AValue.CanonicalForm;
FMaxChars := AValue.MaxChars;
FOnError := AValue.OnError;
end; end;
procedure TXMLTextReader.SetOptions(AParser: TDOMParser); constructor TXMLTextReader.Create(ASrc: TXMLInputSource; ANameTable: THashTable; ASettings: TXMLReaderSettings);
begin
FCtrl := AParser;
if FCtrl = nil then
Exit;
FValidate := FCtrl.Options.Validate;
FPreserveWhitespace := FCtrl.Options.PreserveWhitespace;
FExpandEntities := FCtrl.Options.ExpandEntities;
FCDSectionsAsText := FCtrl.Options.CDSectionsAsText;
FIgnoreComments := FCtrl.Options.IgnoreComments;
FResolveExternals := FCtrl.Options.ResolveExternals;
FNamespaces := FCtrl.Options.Namespaces;
FDisallowDoctype := FCtrl.Options.DisallowDoctype;
FCanonical := FCtrl.Options.CanonicalForm;
FMaxChars := FCtrl.Options.MaxChars;
end;
constructor TXMLTextReader.Create(ASrc: TXMLInputSource; ANameTable: THashTable; AParser: TDOMParser);
var var
InputSrc: TXMLCharSource; InputSrc: TXMLCharSource;
begin begin
Create; Create;
SetOptions(AParser); SetOptions(ASettings);
FNameTable := ANameTable; FNameTable := ANameTable;
ConvertSource(ASrc, InputSrc); ConvertSource(ASrc, InputSrc);
FSource := InputSrc; FSource := InputSrc;
FSource.FReader := Self; FSource.FReader := Self;
end; end;
constructor TXMLTextReader.Create(const uri: XMLString; ANameTable: THashTable; AParser: TDOMParser); constructor TXMLTextReader.Create(const uri: XMLString; ANameTable: THashTable; ASettings: TXMLReaderSettings);
begin begin
Create; Create;
SetOptions(AParser); SetOptions(ASettings);
FNameTable := ANameTable; FNameTable := ANameTable;
if ResolveResource(uri, '', '', FSource) then if ResolveResource(uri, '', '', FSource) then
FSource.FReader := Self FSource.FReader := Self
@ -1361,7 +1359,6 @@ end;
constructor TXMLTextReader.Create(var AFile: Text; ANameTable: THashTable); constructor TXMLTextReader.Create(var AFile: Text; ANameTable: THashTable);
begin begin
SetNametable(ANameTable); SetNametable(ANameTable);
Create;
FSource := TXMLFileInputSource.Create(AFile); FSource := TXMLFileInputSource.Create(AFile);
FSource.FReader := Self; FSource.FReader := Self;
end; end;
@ -1369,7 +1366,6 @@ end;
constructor TXMLTextReader.Create(AStream: TStream; const ABaseUri: XMLString; ANameTable: THashTable); constructor TXMLTextReader.Create(AStream: TStream; const ABaseUri: XMLString; ANameTable: THashTable);
begin begin
SetNametable(ANameTable); SetNametable(ANameTable);
Create;
FSource := TXMLStreamInputSource.Create(AStream, False); FSource := TXMLStreamInputSource.Create(AStream, False);
FSource.SourceURI := ABaseUri; FSource.SourceURI := ABaseUri;
FSource.FReader := Self; FSource.FReader := Self;
@ -1378,10 +1374,19 @@ end;
constructor TXMLTextReader.Create(ASrc: TXMLCharSource; AParent: TXMLTextReader); constructor TXMLTextReader.Create(ASrc: TXMLCharSource; AParent: TXMLTextReader);
begin begin
FNameTable := AParent.FNameTable; FNameTable := AParent.FNameTable;
Create;
FSource := ASrc; FSource := ASrc;
FSource.FReader := Self; FSource.FReader := Self;
SetOptions(AParent.FCtrl);
FValidate := AParent.FValidate;
FPreserveWhitespace := AParent.FPreserveWhitespace;
FExpandEntities := AParent.FExpandEntities;
FCDSectionsAsText := AParent.FCDSectionsAsText;
FIgnoreComments := AParent.FIgnoreComments;
FNamespaces := AParent.FNamespaces;
FDisallowDoctype := AParent.FDisallowDoctype;
FCanonical := AParent.FCanonical;
FMaxChars := AParent.FMaxChars;
FOnError := AParent.FOnError;
end; end;
destructor TXMLTextReader.Destroy; destructor TXMLTextReader.Destroy;
@ -1419,6 +1424,12 @@ end;
procedure TXMLTextReader.AfterConstruction; procedure TXMLTextReader.AfterConstruction;
begin begin
BufAllocate(FName, 128);
BufAllocate(FValue, 512);
SetLength(FNodeStack, 16);
SetLength(FValidators, 16);
FNesting := 0; FNesting := 0;
FValidatorNesting := 0; FValidatorNesting := 0;
FCurrNode := @FNodeStack[0]; FCurrNode := @FNodeStack[0];
@ -4402,7 +4413,6 @@ end;
procedure ReadDTDFile(out ADoc: TXMLDocument; f: TStream; const ABaseURI: String); procedure ReadDTDFile(out ADoc: TXMLDocument; f: TStream; const ABaseURI: String);
var var
Reader: TXMLTextReader; Reader: TXMLTextReader;
Src: TXMLCharSource;
ldr: TLoader; ldr: TLoader;
begin begin
ADoc := TXMLDocument.Create; ADoc := TXMLDocument.Create;