手写代码:
XML格式化使用msxml引擎,Delphi代码如下:
使用实例:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
unit uXMLFormat;
interfaceuses SysUtils, ActiveX, msxml;
function PrettyFormat(const AXML: String): String;
implementationconst 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.
|
使用实例:
|
1
|
Memo2.Text := PrettyFormat('<root><budded/><who/></root>');
|
格式化后结果:
|
1
2
3
4
|
<root>
<budded/>
<who/>
</root>
|
--------------------------------------------------------------------------------------------------------
无需那么复杂,设置XMLDocument的Options属性就可以了,doNodeAutoIndent 才是关键的。举个例子:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
uses XMLIntf,XMLDoc;
procedure TForm1.Button1Click(Sender: TObject);
var xmlDoc: IXMLDocument;
aNode: IXMLNode;
begin xmlDoc := TXMLDocument.Create(nil);
try
// 加入版本信息
xmlDoc.Active := True;
xmlDoc.Version := '1.0';
xmlDoc.Encoding :='GB2312';
xmlDoc.Options := xmlDoc.Options + [doNodeAutoIndent];
// 加入根结点
aNode := xmlDoc.AddChild('RootNode');
// 加入子结点
aNode := aNode.AddChild('ChildNode');
// 设置子结点属性
aNode.SetAttribute('Name', '名称');
aNode.SetAttribute('Len', '长度');
// 设置子结点内容
aNode.Text := '文本内容';
xmlDoc.SaveToFile('C:\ccrun\123.xml');
finally
xmlDoc := nil ;
end;
end;
|
参考:http://bbs.csdn.net/topics/310071629