mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 06:29:38 +02:00
* xmlread.pp, continued reducing DOM dependencies:
* TContentParticle only stores and compares a pointer to an element definition, a particular type of that definition doesn't matter - so change it to TObject. * In case of mixed content model, assign Type and Quantity to the root content particle, and process it the same way as element-only models. * While parsing, store entities in THashTable instead of TDOMNamedNodeMap. * Assign Prefix to element and attribute NodeData. git-svn-id: trunk@16208 -
This commit is contained in:
parent
a723c86cb1
commit
b585a6a1d0
@ -284,12 +284,12 @@ type
|
|||||||
public
|
public
|
||||||
CPType: TCPType;
|
CPType: TCPType;
|
||||||
CPQuant: TCPQuant;
|
CPQuant: TCPQuant;
|
||||||
Def: TDOMElementDef;
|
Def: TObject;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function Add: TContentParticle;
|
function Add: TContentParticle;
|
||||||
function IsRequired: Boolean;
|
function IsRequired: Boolean;
|
||||||
function FindFirst(aDef: TDOMElementDef): TContentParticle;
|
function FindFirst(aDef: TObject): TContentParticle;
|
||||||
function FindNext(aDef: TDOMElementDef; ChildIdx: Integer): TContentParticle;
|
function FindNext(aDef: TObject; ChildIdx: Integer): TContentParticle;
|
||||||
function MoreRequired(ChildIdx: Integer): Boolean;
|
function MoreRequired(ChildIdx: Integer): Boolean;
|
||||||
property ChildCount: Integer read GetChildCount;
|
property ChildCount: Integer read GetChildCount;
|
||||||
property Children[Index: Integer]: TContentParticle read GetChild;
|
property Children[Index: Integer]: TContentParticle read GetChild;
|
||||||
@ -300,6 +300,8 @@ type
|
|||||||
// generic members
|
// generic members
|
||||||
FNext: PNodeData;
|
FNext: PNodeData;
|
||||||
FQName: PHashItem;
|
FQName: PHashItem;
|
||||||
|
FPrefix: PHashItem;
|
||||||
|
FNsUri: PHashItem;
|
||||||
FNodeType: TXMLNodeType;
|
FNodeType: TXMLNodeType;
|
||||||
FDOMNode: TDOMNode_WithChildren; // temporary
|
FDOMNode: TDOMNode_WithChildren; // temporary
|
||||||
|
|
||||||
@ -355,7 +357,8 @@ type
|
|||||||
FStandalone: Boolean; // property of Doc ?
|
FStandalone: Boolean; // property of Doc ?
|
||||||
FNamePages: PByteArray;
|
FNamePages: PByteArray;
|
||||||
FDocType: TDOMDocumentTypeEx; // a shortcut
|
FDocType: TDOMDocumentTypeEx; // a shortcut
|
||||||
FPEMap: TDOMNamedNodeMap;
|
FPEMap: THashTable;
|
||||||
|
FGEMap: THashTable;
|
||||||
FIDRefs: TFPList;
|
FIDRefs: TFPList;
|
||||||
FNotationRefs: TFPList;
|
FNotationRefs: TFPList;
|
||||||
FCurrContentType: TElementContentType;
|
FCurrContentType: TElementContentType;
|
||||||
@ -1347,6 +1350,7 @@ begin
|
|||||||
while ContextPop(True) do; // clean input stack
|
while ContextPop(True) do; // clean input stack
|
||||||
FSource.Free;
|
FSource.Free;
|
||||||
FPEMap.Free;
|
FPEMap.Free;
|
||||||
|
FGEMap.Free;
|
||||||
ClearRefs(FNotationRefs);
|
ClearRefs(FNotationRefs);
|
||||||
ClearRefs(FIDRefs);
|
ClearRefs(FIDRefs);
|
||||||
FNsAttHash.Free;
|
FNsAttHash.Free;
|
||||||
@ -1799,12 +1803,12 @@ var
|
|||||||
PEName: WideString;
|
PEName: WideString;
|
||||||
PEnt: TDOMEntityEx;
|
PEnt: TDOMEntityEx;
|
||||||
begin
|
begin
|
||||||
SetString(PEName, FName.Buffer, FName.Length);
|
|
||||||
PEnt := nil;
|
PEnt := nil;
|
||||||
if Assigned(FPEMap) then
|
if Assigned(FPEMap) then
|
||||||
PEnt := FPEMap.GetNamedItem(PEName) as TDOMEntityEx;
|
PEnt := FPEMap.Get(FName.Buffer, FName.Length) as TDOMEntityEx;
|
||||||
if PEnt = nil then
|
if PEnt = nil then
|
||||||
begin
|
begin
|
||||||
|
SetString(PEName, FName.Buffer, FName.Length);
|
||||||
ValidationError('Undefined parameter entity ''%s'' referenced', [PEName], FName.Length+2);
|
ValidationError('Undefined parameter entity ''%s'' referenced', [PEName], FName.Length+2);
|
||||||
// cease processing declarations, unless document is standalone.
|
// cease processing declarations, unless document is standalone.
|
||||||
FDTDProcessed := FStandalone;
|
FDTDProcessed := FStandalone;
|
||||||
@ -2315,6 +2319,8 @@ begin
|
|||||||
FSource.NextChar;
|
FSource.NextChar;
|
||||||
if (not CheckForChar('*')) and (CP.ChildCount > 0) then
|
if (not CheckForChar('*')) and (CP.ChildCount > 0) then
|
||||||
FatalError(WideChar('*'));
|
FatalError(WideChar('*'));
|
||||||
|
CP.CPQuant := cqZeroOrMore;
|
||||||
|
CP.CPType := ctChoice;
|
||||||
end
|
end
|
||||||
else // Children section [47]
|
else // Children section [47]
|
||||||
begin
|
begin
|
||||||
@ -2510,21 +2516,26 @@ end;
|
|||||||
|
|
||||||
procedure TXMLReader.ParseEntityDecl; // [70]
|
procedure TXMLReader.ParseEntityDecl; // [70]
|
||||||
var
|
var
|
||||||
IsPE: Boolean;
|
IsPE, Exists: Boolean;
|
||||||
Entity: TDOMEntityEx;
|
Entity: TDOMEntityEx;
|
||||||
Map: TDOMNamedNodeMap;
|
Map: THashTable;
|
||||||
|
Item: PHashItem;
|
||||||
begin
|
begin
|
||||||
if not SkipWhitespace(True) then
|
if not SkipWhitespace(True) then
|
||||||
FatalError('Expected whitespace');
|
FatalError('Expected whitespace');
|
||||||
IsPE := False;
|
IsPE := CheckForChar('%');
|
||||||
Map := FDocType.Entities;
|
if IsPE then // [72]
|
||||||
if CheckForChar('%') then // [72]
|
|
||||||
begin
|
begin
|
||||||
ExpectWhitespace;
|
ExpectWhitespace;
|
||||||
IsPE := True;
|
|
||||||
if FPEMap = nil then
|
if FPEMap = nil then
|
||||||
FPEMap := TDOMNamedNodeMap.Create(FDocType, ENTITY_NODE);
|
FPEMap := THashTable.Create(64, True);
|
||||||
Map := FPEMap;
|
Map := FPEMap;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if FGEMap = nil then
|
||||||
|
FGEMap := THashTable.Create(64, False);
|
||||||
|
Map := FGEMap;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Entity := TDOMEntityEx.Create(Doc);
|
Entity := TDOMEntityEx.Create(Doc);
|
||||||
@ -2534,6 +2545,7 @@ begin
|
|||||||
Entity.FIsPE := IsPE;
|
Entity.FIsPE := IsPE;
|
||||||
Entity.FName := ExpectName;
|
Entity.FName := ExpectName;
|
||||||
CheckNCName;
|
CheckNCName;
|
||||||
|
Item := Map.FindOrAdd(FName.Buffer, FName.Length, Exists);
|
||||||
ExpectWhitespace;
|
ExpectWhitespace;
|
||||||
|
|
||||||
// remember where the entity is declared
|
// remember where the entity is declared
|
||||||
@ -2573,8 +2585,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// Repeated declarations of same entity are legal but must be ignored
|
// Repeated declarations of same entity are legal but must be ignored
|
||||||
if FDTDProcessed and (Map.GetNamedItem(Entity.FName) = nil) then
|
if FDTDProcessed and not Exists then
|
||||||
Map.SetNamedItem(Entity)
|
begin
|
||||||
|
Item^.Data := Entity;
|
||||||
|
if not IsPE then
|
||||||
|
FDocType.Entities.SetNamedItem(Entity);
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Entity.Free;
|
Entity.Free;
|
||||||
end;
|
end;
|
||||||
@ -3038,6 +3054,12 @@ begin
|
|||||||
PushVC(NewElem, ElDef); // this increases FNesting
|
PushVC(NewElem, ElDef); // this increases FNesting
|
||||||
FCurrNode^.FQName := ElName;
|
FCurrNode^.FQName := ElName;
|
||||||
FCurrNode^.FNodeType := ntElement;
|
FCurrNode^.FNodeType := ntElement;
|
||||||
|
if FNamespaces then
|
||||||
|
begin
|
||||||
|
FNSHelper.StartElement;
|
||||||
|
if FColonPos > 0 then
|
||||||
|
FCurrNode^.FPrefix := FNSHelper.GetPrefix(FName.Buffer, FColonPos-1);
|
||||||
|
end;
|
||||||
|
|
||||||
while (FSource.FBuf^ <> '>') and (FSource.FBuf^ <> '/') do
|
while (FSource.FBuf^ <> '>') and (FSource.FBuf^ <> '/') do
|
||||||
begin
|
begin
|
||||||
@ -3254,8 +3276,6 @@ var
|
|||||||
PrefixCount: Integer;
|
PrefixCount: Integer;
|
||||||
b: TBinding;
|
b: TBinding;
|
||||||
begin
|
begin
|
||||||
FNSHelper.StartElement;
|
|
||||||
|
|
||||||
PrefixCount := 0;
|
PrefixCount := 0;
|
||||||
if Element.HasAttributes then
|
if Element.HasAttributes then
|
||||||
begin
|
begin
|
||||||
@ -3410,7 +3430,10 @@ begin
|
|||||||
EndPos := StartPos;
|
EndPos := StartPos;
|
||||||
while (EndPos <= L) and (aValue[EndPos] <> #32) do
|
while (EndPos <= L) and (aValue[EndPos] <> #32) do
|
||||||
Inc(EndPos);
|
Inc(EndPos);
|
||||||
Entity := TDOMEntity(FDocType.Entities.GetNamedItem(Copy(aValue, StartPos, EndPos-StartPos)));
|
if Assigned(FGEMap) then
|
||||||
|
Entity := TDOMEntity(FGEMap.Get(@aValue[StartPos], EndPos-StartPos))
|
||||||
|
else
|
||||||
|
Entity := nil;
|
||||||
if (Entity = nil) or (Entity.NotationName = '') then
|
if (Entity = nil) or (Entity.NotationName = '') then
|
||||||
ValidationError('Attribute ''%s'' type mismatch', [Attr.Name], -1);
|
ValidationError('Attribute ''%s'' type mismatch', [Attr.Name], -1);
|
||||||
StartPos := EndPos + 1;
|
StartPos := EndPos + 1;
|
||||||
@ -3522,6 +3545,8 @@ begin
|
|||||||
Result := AllocNodeData(FNesting + FAttrCount + 1);
|
Result := AllocNodeData(FNesting + FAttrCount + 1);
|
||||||
Result^.FNodeType := ntAttribute;
|
Result^.FNodeType := ntAttribute;
|
||||||
Result^.FQName := AName;
|
Result^.FQName := AName;
|
||||||
|
Result^.FPrefix := nil;
|
||||||
|
Result^.FNsUri := nil;
|
||||||
Inc(FAttrCount);
|
Inc(FAttrCount);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3589,6 +3614,7 @@ begin
|
|||||||
FCurrNode^.FElementDef := aElDef;
|
FCurrNode^.FElementDef := aElDef;
|
||||||
FCurrNode^.FCurCP := nil;
|
FCurrNode^.FCurCP := nil;
|
||||||
FCurrNode^.FFailed := False;
|
FCurrNode^.FFailed := False;
|
||||||
|
FCurrNode^.FPrefix := nil;
|
||||||
UpdateConstraints;
|
UpdateConstraints;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3617,7 +3643,6 @@ end;
|
|||||||
|
|
||||||
function TNodeData.IsElementAllowed(Def: TDOMElementDef): Boolean;
|
function TNodeData.IsElementAllowed(Def: TDOMElementDef): Boolean;
|
||||||
var
|
var
|
||||||
I: Integer;
|
|
||||||
Next: TContentParticle;
|
Next: TContentParticle;
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
@ -3625,18 +3650,12 @@ begin
|
|||||||
if Assigned(Def) and Assigned(FElementDef) then
|
if Assigned(Def) and Assigned(FElementDef) then
|
||||||
begin
|
begin
|
||||||
case FElementDef.ContentType of
|
case FElementDef.ContentType of
|
||||||
ctMixed: begin
|
|
||||||
for I := 0 to FElementDef.RootCP.ChildCount-1 do
|
|
||||||
begin
|
|
||||||
if Def = FElementDef.RootCP.Children[I].Def then
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
Result := False;
|
|
||||||
end;
|
|
||||||
|
|
||||||
ctEmpty: Result := False;
|
ctEmpty: Result := False;
|
||||||
|
|
||||||
ctChildren: begin
|
ctChildren, ctMixed: begin
|
||||||
|
if FFailed then // if already detected a mismatch, don't waste time
|
||||||
|
Exit;
|
||||||
if FCurCP = nil then
|
if FCurCP = nil then
|
||||||
Next := FElementDef.RootCP.FindFirst(Def)
|
Next := FElementDef.RootCP.FindFirst(Def)
|
||||||
else
|
else
|
||||||
@ -3733,7 +3752,7 @@ begin
|
|||||||
Result := FParent.MoreRequired(FIndex);
|
Result := FParent.MoreRequired(FIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TContentParticle.FindFirst(aDef: TDOMElementDef): TContentParticle;
|
function TContentParticle.FindFirst(aDef: TObject): TContentParticle;
|
||||||
var
|
var
|
||||||
I: Integer;
|
I: Integer;
|
||||||
begin
|
begin
|
||||||
@ -3759,7 +3778,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TContentParticle.FindNext(aDef: TDOMElementDef;
|
function TContentParticle.FindNext(aDef: TObject;
|
||||||
ChildIdx: Integer): TContentParticle;
|
ChildIdx: Integer): TContentParticle;
|
||||||
var
|
var
|
||||||
I: Integer;
|
I: Integer;
|
||||||
|
Loading…
Reference in New Issue
Block a user