unit uXMLFormat;
interface
uses
SysUtils, ActiveX, msxml;
function PrettyFormat( const AXML: String ): String ;
implementation
const
SMSDOMNotInstalled = ‘Microsoft MSXML 4.0 or upper is not installed.‘ ;
// msxml parser 4.0
ProgID_FreeThreadedDOMDocument40 = ‘Msxml2.FreeThreadedDOMDocument.4.0‘ ;
// msxml parser 6.0
ProgID_FreeThreadedDOMDocument60 = ‘Msxml2.FreeThreadedDOMDocument.6.0‘ ;
type
EMSXMLDomException = class (Exception);
function TryObjectCreateFromProgID( const ProgIDList: array of PWideChar ): IUnknown; overload;
var
I: Integer ;
FClsID: TGUID;
Status: HResult;
begin
for I := Low(ProgIDList) to High(ProgIDList) do
if Succeeded(CLSIDFromProgID(ProgIDList[I], FClsID)) then
begin
Status := CoCreateInstance(FClsID, nil , CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, IUnknown, Result);
if Status = S_OK then Exit;
end ;
end ;
function CreateDOMDocument: IXMLDOMDocument;
begin
Result := TryObjectCreateFromProgID([ProgID_FreeThreadedDOMDocument60, ProgID_FreeThreadedDOMDocument40]) as IXMLDOMDocument;
if not Assigned(Result) then
raise EMSXMLDomException . Create(SMSDOMNotInstalled);
end ;
function PrettyFormat( const AXML: String ): String ;
var
FXMLDoc: IXMLDOMDocument;
procedure TraverseNode(Node: IXMLDOMNode; Indent: string );
const
IndentLevel = # 9 ;
var
LineBreak: IXMLDOMNode;
ChildNode, NextNode: IXMLDOMNode;
AnyChildNode: Boolean ;
begin
if Node = nil then
Exit;
AnyChildNode:= False ;
ChildNode:= Node . Get_firstChild;
while ChildNode <> nil do
begin
NextNode:= ChildNode . nextSibling;
if ChildNode . nodeType = NODE_ELEMENT then
begin
AnyChildNode:= True ;
// Insert LineBreak before each child Node
LineBreak:= FXMLDoc . createTextNode(sLineBreak +
Indent + IndentLevel);
Node . insertBefore(LineBreak, ChildNode);
TraverseNode(ChildNode, Indent + IndentLevel);
end ;
ChildNode:= NextNode;
end ;
if (Node . nodeType = NODE_ELEMENT) and AnyChildNode then
begin
// Add LineBreak after Node
ChildNode:= NextNode;
LineBreak:= FXMLDoc . createTextNode(sLineBreak + Indent);
Node . appendChild(LineBreak);
end ;
end ;
begin
Result := AXML;
FXMLDoc := CreateDOMDocument;
if Assigned(FXMLDoc) and FXMLDoc . loadXML(AXML) then
begin
TraverseNode(FXMLDoc . documentElement, ‘‘ );
Result := FXMLDoc . xml;
end ;
end ;
end .
|