mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-26 14:50:50 +02:00
MG: accelerated xmlread and xmlwrite
git-svn-id: trunk@1797 -
This commit is contained in:
parent
77fcbcd0dc
commit
d395762f08
@ -72,8 +72,10 @@ type
|
|||||||
|
|
||||||
{$IFDEF ver1_0}
|
{$IFDEF ver1_0}
|
||||||
DOMString = String;
|
DOMString = String;
|
||||||
|
DOMPChar = PChar;
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
DOMString = WideString;
|
DOMString = WideString;
|
||||||
|
DOMPChar = PWideChar;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
|
||||||
@ -749,16 +751,33 @@ end;
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function CompareDOMStrings(const s1, s2: DOMPChar; l1, l2: integer): integer;
|
||||||
|
var i: integer;
|
||||||
|
begin
|
||||||
|
Result:=l1-l2;
|
||||||
|
i:=1;
|
||||||
|
while (i<=l1) and (Result=0) do begin
|
||||||
|
Result:=ord(s1[i])-ord(s2[i]);
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function CompareDOMNodeWithDOMNode(Data1, Data2: Pointer): integer;
|
function CompareDOMNodeWithDOMNode(Data1, Data2: Pointer): integer;
|
||||||
begin
|
begin
|
||||||
Result:=AnsiCompareStr(TDOMNode(Data1).NodeName,
|
Result:=CompareDOMStrings(DOMPChar(TDOMNode(Data1).NodeName),
|
||||||
TDOMNode(Data2).NodeName);
|
DOMPChar(TDOMNode(Data2).NodeName),
|
||||||
|
length(TDOMNode(Data1).NodeName),
|
||||||
|
length(TDOMNode(Data2).NodeName)
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CompareDOMStringWithDOMNode(Data1, Data2: Pointer): integer;
|
function CompareDOMStringWithDOMNode(Data1, Data2: Pointer): integer;
|
||||||
begin
|
begin
|
||||||
Result:=AnsiCompareStr(DOMString(Data1),
|
Result:=CompareDOMStrings(DOMPChar(Data1),
|
||||||
TDOMNode(Data2).NodeName);
|
DOMPChar(TDOMNode(Data2).NodeName),
|
||||||
|
length(DOMString(Data1)),
|
||||||
|
length(TDOMNode(Data2).NodeName)
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1596,6 +1615,9 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.2 2002/07/30 14:36:27 lazarus
|
||||||
|
MG: accelerated xmlread and xmlwrite
|
||||||
|
|
||||||
Revision 1.1 2002/07/30 06:24:05 lazarus
|
Revision 1.1 2002/07/30 06:24:05 lazarus
|
||||||
MG: added a faster version of TXMLConfig
|
MG: added a faster version of TXMLConfig
|
||||||
|
|
||||||
|
@ -89,18 +89,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TXMLConfig.Flush;
|
procedure TXMLConfig.Flush;
|
||||||
var
|
|
||||||
f: Text;
|
|
||||||
begin
|
begin
|
||||||
if Modified then
|
if Modified then
|
||||||
begin
|
begin
|
||||||
AssignFile(f, Filename);
|
WriteXMLFile(doc, Filename);
|
||||||
Rewrite(f);
|
|
||||||
try
|
|
||||||
WriteXMLFile(doc, f);
|
|
||||||
finally
|
|
||||||
CloseFile(f);
|
|
||||||
end;
|
|
||||||
FModified := False;
|
FModified := False;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -111,14 +103,14 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
NodePath: String;
|
NodePath: String;
|
||||||
begin
|
begin
|
||||||
Node := doc.DocumentElement; // MAT: check this
|
Node := doc.DocumentElement;
|
||||||
NodePath := APath;
|
NodePath := APath;
|
||||||
while True do
|
while True do
|
||||||
begin
|
begin
|
||||||
i := Pos('/', NodePath);
|
i := Pos('/', NodePath);
|
||||||
if i = 0 then
|
if i = 0 then
|
||||||
break;
|
break;
|
||||||
Child := Node.FindNode(Copy(NodePath, 1, i - 1)); // MAT: check this
|
Child := Node.FindNode(Copy(NodePath, 1, i - 1));
|
||||||
NodePath := Copy(NodePath, i + 1, Length(NodePath));
|
NodePath := Copy(NodePath, i + 1, Length(NodePath));
|
||||||
if not Assigned(Child) then
|
if not Assigned(Child) then
|
||||||
begin
|
begin
|
||||||
@ -127,7 +119,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
Node := Child;
|
Node := Child;
|
||||||
end;
|
end;
|
||||||
Attr := Node.Attributes.GetNamedItem(NodePath); // MAT: check this
|
Attr := Node.Attributes.GetNamedItem(NodePath);
|
||||||
if Assigned(Attr) then
|
if Assigned(Attr) then
|
||||||
Result := Attr.NodeValue
|
Result := Attr.NodeValue
|
||||||
else
|
else
|
||||||
@ -251,6 +243,9 @@ end;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.2 2002/07/30 14:36:28 lazarus
|
||||||
|
MG: accelerated xmlread and xmlwrite
|
||||||
|
|
||||||
Revision 1.1 2002/07/30 06:24:06 lazarus
|
Revision 1.1 2002/07/30 06:24:06 lazarus
|
||||||
MG: added a faster version of TXMLConfig
|
MG: added a faster version of TXMLConfig
|
||||||
|
|
||||||
|
@ -88,7 +88,9 @@ type
|
|||||||
procedure ExpectWhitespace;
|
procedure ExpectWhitespace;
|
||||||
procedure ExpectString(s: String);
|
procedure ExpectString(s: String);
|
||||||
function CheckFor(s: PChar): Boolean;
|
function CheckFor(s: PChar): Boolean;
|
||||||
|
procedure SkipString(ValidChars: TSetOfChar);
|
||||||
function GetString(ValidChars: TSetOfChar): String;
|
function GetString(ValidChars: TSetOfChar): String;
|
||||||
|
function GetString(BufPos: PChar; Len: integer): String;
|
||||||
|
|
||||||
function GetName(var s: String): Boolean;
|
function GetName(var s: String): Boolean;
|
||||||
function ExpectName: String; // [5]
|
function ExpectName: String; // [5]
|
||||||
@ -200,15 +202,40 @@ begin
|
|||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TXMLReader.GetString(ValidChars: TSetOfChar): String;
|
procedure TXMLReader.SkipString(ValidChars: TSetOfChar);
|
||||||
begin
|
begin
|
||||||
SetLength(Result, 0);
|
|
||||||
while buf[0] in ValidChars do begin
|
while buf[0] in ValidChars do begin
|
||||||
Result := Result + buf[0];
|
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TXMLReader.GetString(ValidChars: TSetOfChar): String;
|
||||||
|
var
|
||||||
|
OldBuf: PChar;
|
||||||
|
i, len: integer;
|
||||||
|
begin
|
||||||
|
OldBuf:=Buf;
|
||||||
|
while buf[0] in ValidChars do begin
|
||||||
|
Inc(buf);
|
||||||
|
end;
|
||||||
|
len:=buf-OldBuf;
|
||||||
|
SetLength(Result, Len);
|
||||||
|
for i:=1 to len do begin
|
||||||
|
Result[i]:=OldBuf[0];
|
||||||
|
inc(OldBuf);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TXMLReader.GetString(BufPos: PChar; Len: integer): string;
|
||||||
|
var i: integer;
|
||||||
|
begin
|
||||||
|
SetLength(Result,Len);
|
||||||
|
for i:=1 to Len do begin
|
||||||
|
Result[i]:=BufPos[0];
|
||||||
|
inc(BufPos);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TXMLReader.ProcessXML(ABuf: PChar; AFilename: String); // [1]
|
procedure TXMLReader.ProcessXML(ABuf: PChar; AFilename: String); // [1]
|
||||||
//var
|
//var
|
||||||
// LastNodeBeforeDoc: TDOMNode;
|
// LastNodeBeforeDoc: TDOMNode;
|
||||||
@ -237,6 +264,7 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
function TXMLReader.GetName(var s: String): Boolean; // [5]
|
function TXMLReader.GetName(var s: String): Boolean; // [5]
|
||||||
|
var OldBuf: PChar;
|
||||||
begin
|
begin
|
||||||
SetLength(s, 0);
|
SetLength(s, 0);
|
||||||
if not (buf[0] in (Letter + ['_', ':'])) then begin
|
if not (buf[0] in (Letter + ['_', ':'])) then begin
|
||||||
@ -244,28 +272,36 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
s := buf[0];
|
OldBuf := buf;
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
s := s + GetString(Letter + ['0'..'9', '.', '-', '_', ':']);
|
SkipString(Letter + ['0'..'9', '.', '-', '_', ':']);
|
||||||
|
s := GetString(OldBuf,buf-OldBuf);
|
||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TXMLReader.ExpectName: String; // [5]
|
function TXMLReader.ExpectName: String; // [5]
|
||||||
|
var OldBuf: PChar;
|
||||||
begin
|
begin
|
||||||
if not (buf[0] in (Letter + ['_', ':'])) then
|
if not (buf[0] in (Letter + ['_', ':'])) then
|
||||||
RaiseExc('Expected letter, "_" or ":" for name, found "' + buf[0] + '"');
|
RaiseExc('Expected letter, "_" or ":" for name, found "' + buf[0] + '"');
|
||||||
|
|
||||||
Result := buf[0];
|
OldBuf := buf;
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
Result := Result + GetString(Letter + ['0'..'9', '.', '-', '_', ':']);
|
SkipString(Letter + ['0'..'9', '.', '-', '_', ':']);
|
||||||
|
Result:=GetString(OldBuf,buf-OldBuf);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TXMLReader.ExpectAttValue(attr: TDOMAttr); // [10]
|
procedure TXMLReader.ExpectAttValue(attr: TDOMAttr); // [10]
|
||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
|
OldBuf: PChar;
|
||||||
|
|
||||||
procedure FlushStringBuffer;
|
procedure FlushStringBuffer;
|
||||||
begin
|
begin
|
||||||
|
if OldBuf<>buf then begin
|
||||||
|
s := s + GetString(OldBuf,buf-OldBuf);
|
||||||
|
OldBuf := buf;
|
||||||
|
end;
|
||||||
if Length(s) > 0 then
|
if Length(s) > 0 then
|
||||||
begin
|
begin
|
||||||
attr.AppendChild(doc.CreateTextNode(s));
|
attr.AppendChild(doc.CreateTextNode(s));
|
||||||
@ -282,6 +318,7 @@ begin
|
|||||||
StrDel[1] := #0;
|
StrDel[1] := #0;
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
SetLength(s, 0);
|
SetLength(s, 0);
|
||||||
|
OldBuf := buf;
|
||||||
while not CheckFor(StrDel) do
|
while not CheckFor(StrDel) do
|
||||||
if buf[0] = '&' then
|
if buf[0] = '&' then
|
||||||
begin
|
begin
|
||||||
@ -289,10 +326,11 @@ begin
|
|||||||
ParseReference(attr);
|
ParseReference(attr);
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
s := s + buf[0];
|
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
end;
|
end;
|
||||||
|
dec(buf);
|
||||||
FlushStringBuffer;
|
FlushStringBuffer;
|
||||||
|
inc(buf);
|
||||||
ResolveEntities(Attr);
|
ResolveEntities(Attr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -300,10 +338,10 @@ function TXMLReader.ExpectPubidLiteral: String;
|
|||||||
begin
|
begin
|
||||||
SetLength(Result, 0);
|
SetLength(Result, 0);
|
||||||
if CheckFor('''') then begin
|
if CheckFor('''') then begin
|
||||||
GetString(PubidChars - ['''']);
|
SkipString(PubidChars - ['''']);
|
||||||
ExpectString('''');
|
ExpectString('''');
|
||||||
end else if CheckFor('"') then begin
|
end else if CheckFor('"') then begin
|
||||||
GetString(PubidChars - ['"']);
|
SkipString(PubidChars - ['"']);
|
||||||
ExpectString('"');
|
ExpectString('"');
|
||||||
end else
|
end else
|
||||||
RaiseExc('Expected quotation marks');
|
RaiseExc('Expected quotation marks');
|
||||||
@ -312,14 +350,16 @@ end;
|
|||||||
function TXMLReader.ParseComment(AOwner: TDOMNode): Boolean; // [15]
|
function TXMLReader.ParseComment(AOwner: TDOMNode): Boolean; // [15]
|
||||||
var
|
var
|
||||||
comment: String;
|
comment: String;
|
||||||
|
OldBuf: PChar;
|
||||||
begin
|
begin
|
||||||
if CheckFor('<!--') then begin
|
if CheckFor('<!--') then begin
|
||||||
SetLength(comment, 0);
|
SetLength(comment, 0);
|
||||||
|
OldBuf := buf;
|
||||||
while (buf[0] <> #0) and (buf[1] <> #0) and
|
while (buf[0] <> #0) and (buf[1] <> #0) and
|
||||||
((buf[0] <> '-') or (buf[1] <> '-')) do begin
|
((buf[0] <> '-') or (buf[1] <> '-')) do begin
|
||||||
comment := comment + buf[0];
|
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
end;
|
end;
|
||||||
|
comment:=GetString(OldBuf,buf-OldBuf);
|
||||||
AOwner.AppendChild(doc.CreateComment(comment));
|
AOwner.AppendChild(doc.CreateComment(comment));
|
||||||
ExpectString('-->');
|
ExpectString('-->');
|
||||||
Result := True;
|
Result := True;
|
||||||
@ -435,7 +475,7 @@ begin
|
|||||||
if CheckFor('[') then
|
if CheckFor('[') then
|
||||||
begin
|
begin
|
||||||
ParseDoctypeDecls;
|
ParseDoctypeDecls;
|
||||||
SkipWhitespace;
|
SkipWhitespace;
|
||||||
end;
|
end;
|
||||||
ExpectString('>');
|
ExpectString('>');
|
||||||
end;
|
end;
|
||||||
@ -589,12 +629,12 @@ function TXMLReader.ParseMarkupDecl: Boolean; // [29]
|
|||||||
end;
|
end;
|
||||||
end else if CheckFor('(') then begin // [59]
|
end else if CheckFor('(') then begin // [59]
|
||||||
SkipWhitespace;
|
SkipWhitespace;
|
||||||
GetString(Nmtoken);
|
SkipString(Nmtoken);
|
||||||
SkipWhitespace;
|
SkipWhitespace;
|
||||||
while not CheckFor(')') do begin
|
while not CheckFor(')') do begin
|
||||||
ExpectString('|');
|
ExpectString('|');
|
||||||
SkipWhitespace;
|
SkipWhitespace;
|
||||||
GetString(Nmtoken);
|
SkipString(Nmtoken);
|
||||||
SkipWhitespace;
|
SkipWhitespace;
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
@ -728,13 +768,15 @@ var
|
|||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
OldBuf: PChar;
|
||||||
begin
|
begin
|
||||||
SetLength(s, 0);
|
SetLength(s, 0);
|
||||||
|
OldBuf := buf;
|
||||||
while not (buf[0] in [#0, '<', '&']) do
|
while not (buf[0] in [#0, '<', '&']) do
|
||||||
begin
|
begin
|
||||||
s := s + buf[0];
|
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
end;
|
end;
|
||||||
|
s:=GetString(OldBuf,buf-OldBuf);
|
||||||
if Length(s) > 0 then
|
if Length(s) > 0 then
|
||||||
begin
|
begin
|
||||||
// Check if s has non-whitespace content
|
// Check if s has non-whitespace content
|
||||||
@ -742,7 +784,7 @@ var
|
|||||||
while (i > 0) and (s[i] in WhitespaceChars) do
|
while (i > 0) and (s[i] in WhitespaceChars) do
|
||||||
Dec(i);
|
Dec(i);
|
||||||
if i > 0 then
|
if i > 0 then
|
||||||
NewElem.AppendChild(doc.CreateTextNode(s));
|
NewElem.AppendChild(doc.CreateTextNode(s));
|
||||||
Result := True;
|
Result := True;
|
||||||
end else
|
end else
|
||||||
Result := False;
|
Result := False;
|
||||||
@ -751,15 +793,17 @@ var
|
|||||||
function ParseCDSect: Boolean; // [18]
|
function ParseCDSect: Boolean; // [18]
|
||||||
var
|
var
|
||||||
cdata: String;
|
cdata: String;
|
||||||
|
OldBuf: PChar;
|
||||||
begin
|
begin
|
||||||
if CheckFor('<![CDATA[') then
|
if CheckFor('<![CDATA[') then
|
||||||
begin
|
begin
|
||||||
SetLength(cdata, 0);
|
SetLength(cdata, 0);
|
||||||
|
OldBuf := buf;
|
||||||
while not CheckFor(']]>') do
|
while not CheckFor(']]>') do
|
||||||
begin
|
begin
|
||||||
cdata := cdata + buf[0];
|
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
end;
|
end;
|
||||||
|
cdata := GetString(OldBuf,buf-OldBuf);
|
||||||
NewElem.AppendChild(doc.CreateCDATASection(cdata));
|
NewElem.AppendChild(doc.CreateCDATASection(cdata));
|
||||||
Result := True;
|
Result := True;
|
||||||
end else
|
end else
|
||||||
@ -879,21 +923,25 @@ end;
|
|||||||
function TXMLReader.ParseExternalID: Boolean; // [75]
|
function TXMLReader.ParseExternalID: Boolean; // [75]
|
||||||
|
|
||||||
function GetSystemLiteral: String;
|
function GetSystemLiteral: String;
|
||||||
|
var
|
||||||
|
OldBuf: PChar;
|
||||||
begin
|
begin
|
||||||
SetLength(Result, 0);
|
SetLength(Result, 0);
|
||||||
if buf[0] = '''' then begin
|
if buf[0] = '''' then begin
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
|
OldBuf := buf;
|
||||||
while (buf[0] <> '''') and (buf[0] <> #0) do begin
|
while (buf[0] <> '''') and (buf[0] <> #0) do begin
|
||||||
Result := Result + buf[0];
|
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
end;
|
end;
|
||||||
|
Result := GetString(OldBuf,buf-OldBuf);
|
||||||
ExpectString('''');
|
ExpectString('''');
|
||||||
end else if buf[0] = '"' then begin
|
end else if buf[0] = '"' then begin
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
|
OldBuf := buf;
|
||||||
while (buf[0] <> '"') and (buf[0] <> #0) do begin
|
while (buf[0] <> '"') and (buf[0] <> #0) do begin
|
||||||
Result := Result + buf[0];
|
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
end;
|
end;
|
||||||
|
Result := GetString(OldBuf,buf-OldBuf);
|
||||||
ExpectString('"');
|
ExpectString('"');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -922,12 +970,14 @@ end;
|
|||||||
function TXMLReader.ParseEncodingDecl: String; // [80]
|
function TXMLReader.ParseEncodingDecl: String; // [80]
|
||||||
|
|
||||||
function ParseEncName: String;
|
function ParseEncName: String;
|
||||||
|
var OldBuf: PChar;
|
||||||
begin
|
begin
|
||||||
if not (buf[0] in ['A'..'Z', 'a'..'z']) then
|
if not (buf[0] in ['A'..'Z', 'a'..'z']) then
|
||||||
RaiseExc('Expected character (A-Z, a-z)');
|
RaiseExc('Expected character (A-Z, a-z)');
|
||||||
Result := buf[0];
|
OldBuf := buf;
|
||||||
Inc(buf);
|
Inc(buf);
|
||||||
Result := Result + GetString(['A'..'Z', 'a'..'z', '0'..'9', '.', '_', '-']);
|
SkipString(['A'..'Z', 'a'..'z', '0'..'9', '.', '_', '-']);
|
||||||
|
Result := GetString(OldBuf,buf-OldBuf);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -966,14 +1016,14 @@ procedure TXMLReader.ResolveEntities(RootNode: TDOMNode);
|
|||||||
if Assigned(NextSibling) and (NextSibling.NodeType = TEXT_NODE) then
|
if Assigned(NextSibling) and (NextSibling.NodeType = TEXT_NODE) then
|
||||||
begin
|
begin
|
||||||
TDOMCharacterData(PrevSibling).AppendData(
|
TDOMCharacterData(PrevSibling).AppendData(
|
||||||
TDOMCharacterData(NextSibling).Data);
|
TDOMCharacterData(NextSibling).Data);
|
||||||
RootNode.RemoveChild(NextSibling);
|
RootNode.RemoveChild(NextSibling);
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
if Assigned(NextSibling) and (NextSibling.NodeType = TEXT_NODE) then
|
if Assigned(NextSibling) and (NextSibling.NodeType = TEXT_NODE) then
|
||||||
begin
|
begin
|
||||||
TDOMCharacterData(NextSibling).InsertData(0, Replacement);
|
TDOMCharacterData(NextSibling).InsertData(0, Replacement);
|
||||||
RootNode.RemoveChild(EntityNode);
|
RootNode.RemoveChild(EntityNode);
|
||||||
end else
|
end else
|
||||||
RootNode.ReplaceChild(Doc.CreateTextNode(Replacement), EntityNode);
|
RootNode.ReplaceChild(Doc.CreateTextNode(Replacement), EntityNode);
|
||||||
end;
|
end;
|
||||||
@ -987,15 +1037,15 @@ begin
|
|||||||
NextSibling := Node.NextSibling;
|
NextSibling := Node.NextSibling;
|
||||||
if Node.NodeType = ENTITY_REFERENCE_NODE then
|
if Node.NodeType = ENTITY_REFERENCE_NODE then
|
||||||
if Node.NodeName = 'amp' then
|
if Node.NodeName = 'amp' then
|
||||||
ReplaceEntityRef(Node, '&')
|
ReplaceEntityRef(Node, '&')
|
||||||
else if Node.NodeName = 'apos' then
|
else if Node.NodeName = 'apos' then
|
||||||
ReplaceEntityRef(Node, '''')
|
ReplaceEntityRef(Node, '''')
|
||||||
else if Node.NodeName = 'gt' then
|
else if Node.NodeName = 'gt' then
|
||||||
ReplaceEntityRef(Node, '>')
|
ReplaceEntityRef(Node, '>')
|
||||||
else if Node.NodeName = 'lt' then
|
else if Node.NodeName = 'lt' then
|
||||||
ReplaceEntityRef(Node, '<')
|
ReplaceEntityRef(Node, '<')
|
||||||
else if Node.NodeName = 'quot' then
|
else if Node.NodeName = 'quot' then
|
||||||
ReplaceEntityRef(Node, '"');
|
ReplaceEntityRef(Node, '"');
|
||||||
Node := NextSibling;
|
Node := NextSibling;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1123,6 +1173,9 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.2 2002/07/30 14:36:28 lazarus
|
||||||
|
MG: accelerated xmlread and xmlwrite
|
||||||
|
|
||||||
Revision 1.1 2002/07/30 06:24:06 lazarus
|
Revision 1.1 2002/07/30 06:24:06 lazarus
|
||||||
MG: added a faster version of TXMLConfig
|
MG: added a faster version of TXMLConfig
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ end;
|
|||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
TOutputProc = procedure(s: String);
|
TOutputProc = procedure(const Buffer; Count: Longint);
|
||||||
|
|
||||||
var
|
var
|
||||||
f: ^Text;
|
f: ^Text;
|
||||||
@ -91,30 +91,56 @@ var
|
|||||||
wrt, wrtln: TOutputProc;
|
wrt, wrtln: TOutputProc;
|
||||||
InsideTextNode: Boolean;
|
InsideTextNode: Boolean;
|
||||||
|
|
||||||
|
procedure Text_Write(const Buffer; Count: Longint);
|
||||||
procedure Text_Write(s: String);
|
var s: string;
|
||||||
begin
|
begin
|
||||||
Write(f^, s);
|
if Count>0 then begin
|
||||||
|
SetLength(s,Count);
|
||||||
|
System.Move(Buffer,s[1],Count);
|
||||||
|
Write(f^, s);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Text_WriteLn(s: String);
|
procedure Text_WriteLn(const Buffer; Count: Longint);
|
||||||
|
var s: string;
|
||||||
begin
|
begin
|
||||||
WriteLn(f^, s);
|
if Count>0 then begin
|
||||||
|
SetLength(s,Count);
|
||||||
|
System.Move(Buffer,s[1],Count);
|
||||||
|
WriteLn(f^, s);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Stream_Write(s: String);
|
procedure Stream_Write(const Buffer; Count: Longint);
|
||||||
begin
|
begin
|
||||||
if Length(s) > 0 then
|
if Count > 0 then
|
||||||
stream.Write(s[1], Length(s));
|
stream.Write(Buffer, Count);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Stream_WriteLn(s: String);
|
procedure Stream_WriteLn(const Buffer; Count: Longint);
|
||||||
begin
|
begin
|
||||||
if Length(s) > 0 then
|
if Count > 0 then
|
||||||
stream.Write(s[1], Length(s));
|
stream.Write(Buffer, Count);
|
||||||
stream.WriteByte(10);
|
stream.WriteByte(10);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure wrtStr(s: string);
|
||||||
|
begin
|
||||||
|
if s<>'' then
|
||||||
|
wrt(s[1],length(s));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure wrtStrLn(s: string);
|
||||||
|
begin
|
||||||
|
if s<>'' then
|
||||||
|
wrtln(s[1],length(s));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure wrtChr(c: char);
|
||||||
|
begin
|
||||||
|
wrt(c,1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Indent handling
|
// Indent handling
|
||||||
@ -160,36 +186,43 @@ begin
|
|||||||
begin
|
begin
|
||||||
if s[EndPos] in SpecialChars then
|
if s[EndPos] in SpecialChars then
|
||||||
begin
|
begin
|
||||||
wrt(Copy(s, StartPos, EndPos - StartPos));
|
wrt(s[StartPos],EndPos - StartPos);
|
||||||
SpecialCharCallback(s[EndPos]);
|
SpecialCharCallback(s[EndPos]);
|
||||||
StartPos := EndPos + 1;
|
StartPos := EndPos + 1;
|
||||||
end;
|
end;
|
||||||
Inc(EndPos);
|
Inc(EndPos);
|
||||||
end;
|
end;
|
||||||
if EndPos > StartPos then
|
if EndPos > StartPos then
|
||||||
wrt(Copy(s, StartPos, EndPos - StartPos));
|
wrt(s[StartPos], EndPos - StartPos);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure AttrSpecialCharCallback(c: Char);
|
procedure AttrSpecialCharCallback(c: Char);
|
||||||
|
const
|
||||||
|
QuotStr = '"';
|
||||||
|
AmpStr = '&';
|
||||||
begin
|
begin
|
||||||
if c = '"' then
|
if c = '"' then
|
||||||
wrt('"')
|
wrt(QuotStr, length(QuotStr))
|
||||||
else if c = '&' then
|
else if c = '&' then
|
||||||
wrt('&')
|
wrt(AmpStr, length(AmpStr))
|
||||||
else
|
else
|
||||||
wrt(c);
|
wrt(c,1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TextnodeSpecialCharCallback(c: Char);
|
procedure TextnodeSpecialCharCallback(c: Char);
|
||||||
|
const
|
||||||
|
ltStr = '<';
|
||||||
|
gtStr = '>';
|
||||||
|
AmpStr = '&';
|
||||||
begin
|
begin
|
||||||
if c = '<' then
|
if c = '<' then
|
||||||
wrt('<')
|
wrt(ltStr, length(ltStr))
|
||||||
else if c = '>' then
|
else if c = '>' then
|
||||||
wrt('>')
|
wrt(gtStr, length(gtStr))
|
||||||
else if c = '&' then
|
else if c = '&' then
|
||||||
wrt('&')
|
wrt(AmpStr, length(AmpStr))
|
||||||
else
|
else
|
||||||
wrt(c);
|
wrt(c,1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -205,31 +238,35 @@ var
|
|||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
if not InsideTextNode then
|
if not InsideTextNode then
|
||||||
wrt(Indent);
|
wrtStr(Indent);
|
||||||
wrt('<' + node.NodeName);
|
wrtChr('<');
|
||||||
|
wrtStr(node.NodeName);
|
||||||
for i := 0 to node.Attributes.Length - 1 do
|
for i := 0 to node.Attributes.Length - 1 do
|
||||||
begin
|
begin
|
||||||
attr := node.Attributes.Item[i];
|
attr := node.Attributes.Item[i];
|
||||||
wrt(' ' + attr.NodeName + '=');
|
wrtChr(' ');
|
||||||
|
wrtStr(attr.NodeName);
|
||||||
|
wrtChr('=');
|
||||||
s := attr.NodeValue;
|
s := attr.NodeValue;
|
||||||
// !!!: Replace special characters in "s" such as '&', '<', '>'
|
// !!!: Replace special characters in "s" such as '&', '<', '>'
|
||||||
wrt('"');
|
wrtChr('"');
|
||||||
ConvWrite(s, AttrSpecialChars, @AttrSpecialCharCallback);
|
ConvWrite(s, AttrSpecialChars, @AttrSpecialCharCallback);
|
||||||
wrt('"');
|
wrtChr('"');
|
||||||
end;
|
end;
|
||||||
Child := node.FirstChild;
|
Child := node.FirstChild;
|
||||||
if Child = nil then
|
if Child = nil then begin
|
||||||
if InsideTextNode then
|
if InsideTextNode then begin
|
||||||
wrt('/>')
|
wrtChr('/'); wrtChr('>');
|
||||||
else
|
end else begin
|
||||||
wrtln('/>')
|
wrtChr('/'); wrtln('>',1);
|
||||||
else
|
end;
|
||||||
|
end else
|
||||||
begin
|
begin
|
||||||
SavedInsideTextNode := InsideTextNode;
|
SavedInsideTextNode := InsideTextNode;
|
||||||
if InsideTextNode or Child.InheritsFrom(TDOMText) then
|
if InsideTextNode or Child.InheritsFrom(TDOMText) then
|
||||||
wrt('>')
|
wrtChr('>')
|
||||||
else
|
else
|
||||||
wrtln('>');
|
wrtln('>',1);
|
||||||
IncIndent;
|
IncIndent;
|
||||||
repeat
|
repeat
|
||||||
if Child.InheritsFrom(TDOMText) then
|
if Child.InheritsFrom(TDOMText) then
|
||||||
@ -239,13 +276,15 @@ begin
|
|||||||
until child = nil;
|
until child = nil;
|
||||||
DecIndent;
|
DecIndent;
|
||||||
if not InsideTextNode then
|
if not InsideTextNode then
|
||||||
wrt(Indent);
|
wrtStr(Indent);
|
||||||
InsideTextNode := SavedInsideTextNode;
|
InsideTextNode := SavedInsideTextNode;
|
||||||
s := '</' + node.NodeName + '>';
|
wrtChr('<');
|
||||||
|
wrtChr('/');
|
||||||
|
wrtStr(node.NodeName);
|
||||||
if InsideTextNode then
|
if InsideTextNode then
|
||||||
wrt(s)
|
wrtChr('>')
|
||||||
else
|
else
|
||||||
wrtln(s);
|
wrtln('>',1);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -264,14 +303,16 @@ end;
|
|||||||
procedure WriteCDATA(node: TDOMNode);
|
procedure WriteCDATA(node: TDOMNode);
|
||||||
begin
|
begin
|
||||||
if InsideTextNode then
|
if InsideTextNode then
|
||||||
wrt('<![CDATA[' + node.NodeValue + ']]>')
|
wrtStr('<![CDATA[' + node.NodeValue + ']]>')
|
||||||
else
|
else
|
||||||
wrtln(Indent + '<![CDATA[' + node.NodeValue + ']]>')
|
wrtStrln(Indent + '<![CDATA[' + node.NodeValue + ']]>')
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure WriteEntityRef(node: TDOMNode);
|
procedure WriteEntityRef(node: TDOMNode);
|
||||||
begin
|
begin
|
||||||
wrt('&' + node.NodeName + ';');
|
wrtChr('&');
|
||||||
|
wrtStr(node.NodeName);
|
||||||
|
wrtChr(';');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure WriteEntity(node: TDOMNode);
|
procedure WriteEntity(node: TDOMNode);
|
||||||
@ -281,23 +322,23 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure WritePI(node: TDOMNode);
|
procedure WritePI(node: TDOMNode);
|
||||||
var
|
|
||||||
s: String;
|
|
||||||
begin
|
begin
|
||||||
s := '<!' + TDOMProcessingInstruction(node).Target + ' ' +
|
wrtChr('<'); wrtChr('!');
|
||||||
TDOMProcessingInstruction(node).Data + '>';
|
wrtStr(TDOMProcessingInstruction(node).Target);
|
||||||
if InsideTextNode then
|
wrtChr(' ');
|
||||||
wrt(s)
|
wrtStr(TDOMProcessingInstruction(node).Data);
|
||||||
else
|
wrtChr('>');
|
||||||
wrtln(Indent + s);
|
if not InsideTextNode then
|
||||||
|
wrtStrln('');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure WriteComment(node: TDOMNode);
|
procedure WriteComment(node: TDOMNode);
|
||||||
begin
|
begin
|
||||||
if InsideTextNode then
|
wrtStr('<!--');
|
||||||
wrt('<!--' + node.NodeValue + '-->')
|
wrtStr(node.NodeValue);
|
||||||
else
|
wrtStr('-->');
|
||||||
wrtln(Indent + '<!--' + node.NodeValue + '-->')
|
if not InsideTextNode then
|
||||||
|
wrtStrln('');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure WriteDocument(node: TDOMNode);
|
procedure WriteDocument(node: TDOMNode);
|
||||||
@ -335,19 +376,19 @@ var
|
|||||||
Child: TDOMNode;
|
Child: TDOMNode;
|
||||||
begin
|
begin
|
||||||
InitWriter;
|
InitWriter;
|
||||||
wrt('<?xml version="');
|
wrtStr('<?xml version="');
|
||||||
if Length(doc.XMLVersion) > 0 then
|
if Length(doc.XMLVersion) > 0 then
|
||||||
wrt(doc.XMLVersion)
|
wrtStr(doc.XMLVersion)
|
||||||
else
|
else
|
||||||
wrt('1.0');
|
wrtStr('1.0');
|
||||||
wrt('"');
|
wrtChr('"');
|
||||||
if Length(doc.Encoding) > 0 then
|
if Length(doc.Encoding) > 0 then
|
||||||
wrt(' encoding="' + doc.Encoding + '"');
|
wrtStr(' encoding="' + doc.Encoding + '"');
|
||||||
wrtln('?>');
|
wrtStrln('?>');
|
||||||
|
|
||||||
if Length(doc.StylesheetType) > 0 then
|
if Length(doc.StylesheetType) > 0 then
|
||||||
// !!!: Can't handle with HRefs which contain special chars (" and so on)
|
// !!!: Can't handle with HRefs which contain special chars (" and so on)
|
||||||
wrtln(Format('<?xml-stylesheet type="%s" href="%s"?>',
|
wrtStrln(Format('<?xml-stylesheet type="%s" href="%s"?>',
|
||||||
[doc.StylesheetType, doc.StylesheetHRef]));
|
[doc.StylesheetType, doc.StylesheetHRef]));
|
||||||
|
|
||||||
indent := '';
|
indent := '';
|
||||||
@ -361,17 +402,30 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure WriteXMLMemStream(doc: TXMLDocument);
|
||||||
|
// internally used by the WriteXMLFile procedures
|
||||||
|
begin
|
||||||
|
Stream:=TMemoryStream.Create;
|
||||||
|
WriteXMLFile(doc,Stream);
|
||||||
|
Stream.Position:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Interface implementation
|
// Interface implementation
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
procedure WriteXMLFile(doc: TXMLDocument; const AFileName: String);
|
procedure WriteXMLFile(doc: TXMLDocument; const AFileName: String);
|
||||||
|
var fs: TFileStream;
|
||||||
begin
|
begin
|
||||||
Stream := TFileStream.Create(AFileName, fmCreate);
|
// write first to memory buffer and then as one whole block to file
|
||||||
wrt := @Stream_Write;
|
WriteXMLMemStream(doc);
|
||||||
wrtln := @Stream_WriteLn;
|
try
|
||||||
RootWriter(doc);
|
fs := TFileStream.Create(AFileName, fmCreate);
|
||||||
Stream.Free;
|
fs.CopyFrom(Stream,Stream.Size);
|
||||||
|
fs.Free;
|
||||||
|
finally
|
||||||
|
Stream.Free;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure WriteXMLFile(doc: TXMLDocument; var AFile: Text);
|
procedure WriteXMLFile(doc: TXMLDocument; var AFile: Text);
|
||||||
@ -425,6 +479,9 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.2 2002/07/30 14:36:28 lazarus
|
||||||
|
MG: accelerated xmlread and xmlwrite
|
||||||
|
|
||||||
Revision 1.1 2002/07/30 06:24:06 lazarus
|
Revision 1.1 2002/07/30 06:24:06 lazarus
|
||||||
MG: added a faster version of TXMLConfig
|
MG: added a faster version of TXMLConfig
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user