Skip to content

Commit

Permalink
Added contextual level param to make possible to indent output
Browse files Browse the repository at this point in the history
When level = -1 : no indent expected (auclosing nodes, param names, param values)
When level >= 0 : current level of indentation (no "wordwrapping" support for long sequences of node attributes), can be used to generate a string of tabs : hgourvest#13#10 + StringOfChar(#9, level) or a string of spaces : hgourvest#13#10 + StringOfChar(' ', 2*level) to indent with two spaces.
  • Loading branch information
PierreYager committed Jan 30, 2017
1 parent 90b8fbc commit 0602faf
Showing 1 changed file with 32 additions and 15 deletions.
47 changes: 32 additions & 15 deletions superxmlparser.pas
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ function XMLParseFile(const FileName: string; pack: Boolean = false; onpi: TOnPr

{$IFDEF UNICODE}
type
TXMLWriteMethod = reference to procedure(const data: string);
procedure XMLWrite(const node: ISuperObject; const method: TXMLWriteMethod);
TXMLWriteMethod = reference to procedure(const data: string; level: Integer);

procedure XMLWrite(const node: ISuperObject; const method: TXMLWriteMethod; level: Integer = 0);
{$ENDIF}

const
Expand Down Expand Up @@ -110,19 +111,23 @@ implementation
TSuperXMLEncoding = ({$IFNDEF UNIX}xnANSI,{$ENDIF} xnUTF8, xnUnicode);

{$IFDEF UNICODE}
procedure XMLWrite(const node: ISuperObject; const method: TXMLWriteMethod);
procedure XMLWrite(const node: ISuperObject; const method: TXMLWriteMethod;
level: Integer);

procedure Escape(const str: string);
var
var
p1, p2: PChar;

procedure push(const data: string);
begin
if p2 > p1 then
method(Copy(p1, 0, p2-p1));
method(Copy(p1, 0, p2-p1), -1);
Inc(p2);
p1 := p2;
if data <> '' then
method(data);
method(data, -1);
end;

begin
p1 := PChar(str);
p2 := p1;
Expand All @@ -145,25 +150,37 @@ implementation
var
o: ISuperObject;
ent: TSuperAvlEntry;
has_child_nodes: Boolean;
begin
method('<' + node.S[xmlname]);
method('<' + node.S[xmlname], level);

if ObjectIsType(node[xmlattributes], stObject) then
for ent in node[xmlattributes].AsObject do
begin
method(' ' + ent.Name + '="');
method(' ' + ent.Name + '="', -1);
Escape(ent.Value.AsString);
method('"');
method('"', -1);
end;

if ObjectIsType(node[xmlchildren], stArray) then
begin
method('>');
method('>', -1);
has_child_nodes := False;
for o in node[xmlchildren] do
if ObjectIsType(o, stString) then
Escape(o.AsString) else
XMLWrite(o, method);
method('</' + node.S[xmlname] + '>');
end else
method('/>');
Escape(o.AsString)
else
begin
XMLWrite(o, method, level + 1);
has_child_nodes := True;
end;
if has_child_nodes then
method('</' + node.S[xmlname] + '>', level)
else
method('</' + node.S[xmlname] + '>', -1)
end
else
method('/>', -1);
end;
{$ENDIF}

Expand Down

0 comments on commit 0602faf

Please sign in to comment.