EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Indent XML in output

Also by EldoS: RawDisk
Access locked and protected files in Windows, read and write disks and partitions and more.
#18425
Posted: 12/10/2011 16:08:41
by Leonardo Herrera (Standard support level)
Joined: 02/14/2011
Posts: 66

Hello folks,

It's been a long week. I've been doing lots of stuff related with signatures and other hairy stuff. Most of them I've already solved, but now I need to just get an XML document and make it pretty (basically, indenting it.)

Do you know an easy way to do this with TElXMLDOMDocument? (I'm currently using an old open source library but I cannot control it at all, and besides I don't like having two XML processors lingering inside my code.)

Any suggestions are most welcome.
Regards,
Leonardo Herrera
#18426
Posted: 12/10/2011 17:19:41
by Dmytro Bogatskyy (EldoS Corp.)

I don't recommend to reformat an xml document If you already have signed it. Of course you can do this prior signing.

Quote
Do you know an easy way to do this with TElXMLDOMDocument?

There is no such method at the moment.
Please check a sample below:
https://www.eldos.com/forum/read.php?F...ssage17768
#18427
Posted: 12/10/2011 17:50:16
by Leonardo Herrera (Standard support level)
Joined: 02/14/2011
Posts: 66

Thank you. That's an improvement. Question: is it possible to add a newline after the processing instruction? I need something like this:
Code
<?xml version="1.0" encoding="ISO-8859-1"?>
<doc>
....
</doc>


On a similar related note, I've had to change one line in the SBXMLCore.pas file so when saving to a stream the encoding is uppercase. Any chance of adding a property to set the encoding to uppercase when saving to a stream? (I know a valid processor shouldn't barf at a lowercase encoding attribute, but I'm dealing with a braindead validator here.)

(By the way, I think some form of serializer with pretty printing would be awesome.)
#18428
Posted: 12/10/2011 18:35:50
by Leonardo Herrera (Standard support level)
Joined: 02/14/2011
Posts: 66

I modified a little bit the code in the link provided, because I didn't like that it added spaces to my text nodes. This works slightly better, at least to my eyes. Any improvements are welcome.
Code
procedure FormatElement(parentNode: TElXMLDOMElement; Level: integer);
var
  node: TElXMLDOMNode;
  S: XMLString;
  i: integer;
  Return: boolean;
begin
  S := #10;
  for i := 0 to Level do
    S := S + #9;
  Return := false;
  node := parentNode.FirstChild;
  while Assigned(node) do
  begin
    if node.NodeType = ntElement then
    begin
      Return := true;
      SBXMLUtils.InsertTextBeforeXMLElement(S, parentNode, node);
      FormatElement(TElXMLDOMElement(node), Level + 1);
    end;
    node := node.NextSibling;
  end;
  if Return and (Level > 0) then
  begin
    S := #10;
    for i := 0 to Level - 1 do
      S := S + #9;
    AddTextToXMLElement(S, TElXMLDOMElement(parentNode));
  end;
end;


Cheers,
Leonardo Herrera
#18429
Posted: 12/11/2011 13:10:36
by Dmytro Bogatskyy (EldoS Corp.)

Quote
Question: is it possible to add a newline after the processing instruction?

Sure, for example:
Code
node := Document.FirstChild;
while Assigned(node) do
begin
  if node.NodeType = ntProcessingInstruction then
  begin
    if Assigned(node.NextSibling) then
      Document.InsertBefore(Document.CreateTextNode(#10), node.NextSibling);
    else
      Document.AppendChild(Document.CreateTextNode(#10));
  end;
  node := node.NextSibling;
end;

Quote
I've had to change one line in the SBXMLCore.pas file so when saving to a stream the encoding is uppercase. Any chance of adding a property to set the encoding to uppercase when saving to a stream?

The simplest way at the moment (without modifying SBXMLCore unit), is to override GetCharsetName method of TElXML8BitCodec class. For example:
Code
uses
  SBXMLCharsets;

type
  TElXML8BitCodec_UpperCase = class (TElXML8BitCodec)
  protected
    function GetCharsetName: string; override;
  end;

function TElXML8BitCodec_UpperCase.GetCharsetName: string;
begin
  Result := inherited GetCharsetName();
  Result := UpperCase(Result);
end;

then call SaveToStream method with
Code
Enc := TElXML8BitCodec_UpperCase.Create('ISO-8859-1');
try
  XMLDocument.SaveToStream(Stream, xcmNone, Enc);
finally
  FreeAndNil(Enc);
end;

I think we could add a property that makes encoding name in upper case to TElXMLCodec class, we'll consider this. Thank you.
#18430
Posted: 12/11/2011 16:59:03
by Leonardo Herrera (Standard support level)
Joined: 02/14/2011
Posts: 66

This looks way better than tampering around with the core code. Thank you very much!
Also by EldoS: CallbackFilter
A component to monitor and control disk activity, track file and directory operations (create, read, write, rename etc.), alter file data, encrypt files, create virtual files.

Reply

Statistics

Topic viewed 1173 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!