views:

1186

answers:

6

hi

Anyone got a ready made function that will take an XML string and return a correctly indented string?

eg

<XML><TAG1>A</TAG1><TAG2><Tag3></Tag3></TAG2></XML>

and will return nicely formatted String in return after inserting linebreaks and tabs or spaces?

Yes I know the code is easy to write but I'm sure someone else has already written it.

Update: Thanks to Bruce McGee and all the others that answered. Bruce's suggestion was just what I was after thanks.

+3  A: 

Using OmniXML:

program TestIndentXML;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  OmniXML,
  OmniXMLUtils;

function IndentXML(const xml: string): string;
var
  xmlDoc: IXMLDocument;
begin
  Result := '';
  xmlDoc := CreateXMLDoc;
  if not XMLLoadFromAnsiString(xmlDoc, xml) then
    Exit;
  Result := XMLSaveToAnsiString(xmlDoc, ofIndent);
end;

begin
  Writeln(IndentXML('<XML><TAG1>A</TAG1><TAG2><Tag3></Tag3></TAG2></XML>'));
  Readln;
end.

The code fragment above is released to public domain.

gabr
+3  A: 

Using XSLT...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="/">
        <xsl:copy-of select="."/>
    </xsl:template>
</xsl:stylesheet>
dacracot
PS - This will collapse <Tag3></Tag3> to <Tag3/>.
dacracot
A: 

http://xerces.apache.org/xerces-j/apiDocs/org/apache/xml/serialize/OutputFormat.html

If you are using Java, then you can use OutputFormat class. See the setIndenting() method.

I cant recall, there are some other options too, I will look for them and update if I find them.

edit : Also check the setLineWidth() method.

Satish Motwani
Look at the tags, he is using Delphi.
gabr
+2  A: 

The XML Document DOM object build into Delphi has a pretty formatting option. You just load your XML into it and save it back out, and if you have that option set then it makes it all pretty.

I'll look it up and update this answer.

Jim McKeeth
you should have looked it up before answering :)
Osama ALASSIRY
Don't always have time, but it would have been nice.
Jim McKeeth
+3  A: 

The RTL has FormatXMLData in XMLDoc.pas that accepts and returns strings.

Bruce McGee
+1  A: 

I have used Tidy with libtidy from Michael Elsdörfer. It give you heaps of options and you can configure them externally to the application. Also applicable to HTML.

This is some very rough code that I used. Do with it as you please.

function TForm1.DoTidy(const Source: string): string;
var
  Tidy              : TLibTidy;
begin
  if not TidyGlobal.LoadTidyLibrary('libtidy.dll') then
  begin
    //    Application.MessageBox('TidyLib is not available.', 'Error', 16);
    //    exit;
    raise Exception.Create('Cannot load TidyLib.dll');
  end;
  Tidy := TLibTidy.Create(Self);
  try
    Tidy.LoadConfigFile(ExtractFilePath(Application.ExeName) +
      'tidyconfig.txt');
    //    Tidy.Configuration.IndentContent := tsYes;
    //    Tidy.Configuration.IndentSpaces := 5;
    //    Tidy.Configuration.UpperCaseTags := False;
    //    Tidy.Configuration.NumEntities := True;
    //    Tidy.Configuration.AccessibilityCheckLevel := 2;
    //    Tidy.Configuration.InlineTags := 'foo,bar';
    //    Tidy.Configuration.XmlDecl := True;
    //    Tidy.Configuration.XmlTags := True;
    //    Tidy.Configuration.CharEncoding := TidyUTF8;
    //    Tidy.Configuration.WrapLen := 0;
    //    Tidy.SaveConfigFile('tidyconfig.txt');
    Tidy.ParseString(Source);
    Result := Tidy.RunDiagnosticsAndRepair;
  finally
    Tidy.Free;
  end;
end;
Richard A
Thanks for the correction, Bruce.
Richard A