Buen código para formatear una cadena xml
delphi pretty-print (5)
El RTL tiene FormatXMLData en XMLDoc.pas que acepta y devuelve cadenas.
¿Alguien tiene una función preparada que tomará una cadena XML y devolverá una cadena con sangría correcta?
p.ej
<XML><TAG1>A</TAG1><TAG2><Tag3></Tag3></TAG2></XML>
y devolverá Cadena muy formateada a cambio después de insertar linebreaks y pestañas o espacios?
He usado Tidy con libtidy de Michael Elsdörfer. Le da un montón de opciones y puede configurarlas externamente a la aplicación. También aplicable a HTML.
Este es un código muy duro que utilicé. Hazlo como quieras.
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;
La construcción de objetos XML Document DOM en Delphi tiene una bonita opción de formateo. Simplemente cargue su XML en él y guárdelo de nuevo, y si tiene esa opción configurada, todo resulta muy bonito.
Lo buscaré y actualizaré esta respuesta.
Usando 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.
El fragmento de código anterior se lanza al dominio público.
Usando 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>