手写代码:
 
XML格式化使用msxml引擎,Delphi代码如下:

Delphi/Pascal code

 

?

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;
 
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.

使用实例:

 
Delphi/Pascal code

 

?

1
Memo2.Text := PrettyFormat('<root><budded/><who/></root>');
 
格式化后结果:

XML/HTML code

 

?

1
2
3
4
<root>
    <budded/>
    <who/>
</root>
--------------------------------------------------------------------------------------------------------
无需那么复杂,设置XMLDocument的Options属性就可以了,doNodeAutoIndent 才是关键的。举个例子:

Delphi/Pascal code

 

?

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

TXMLDocument换行的两种方案的更多相关文章

  1. 详解Grunt插件之LiveReload实现页面自动刷新(两种方案)

    http://www.jb51.net/article/70415.htm    含Grunt系列教程 这篇文章主要通过两种方案详解Grunt插件之LiveReload实现页面自动刷新,需要的朋友可以 ...

  2. Linux下实现秒级定时任务的两种方案

    Linux下实现秒级定时任务的两种方案(Crontab 每秒运行): 第一种方案,当然是写一个后台运行的脚本一直循环,然后每次循环sleep一段时间. while true ;do command s ...

  3. [转载]Java操作Excel文件的两种方案

    微软在桌面系统上的成功,令我们不得不大量使用它的办公产品,如:Word,Excel.时至今日,它的源代码仍然不公开已封锁了我们的进一步应用和开发.在我们实际开发企业办公系统的过程中,常常有客户这样子要 ...

  4. .Net Core下使用RabbitMQ比较完备的两种方案(虽然代码有点惨淡,不过我会完善)

    一.前言     上篇说给大家来写C#和Java的方案,最近工作也比较忙,迟到了一些,我先给大家补上C#的方案,另外如果没看我上篇博客的人最好看一下,否则你可能看的云里雾里的,这里我就不进行具体的方案 ...

  5. 比较好用的移动端适配的两种方案及flexible和px2rem-loader在webpack下的配置

    移动端适配,目前自己常用的两种 方案,参考以下两篇好文 方案一:使用lib-flexible包 https://www.w3cplus.com/mobile/lib-flexible-for-html ...

  6. Spring Boot 配置文件密码加密两种方案

    Spring Boot 配置文件密码加密两种方案 jasypt 加解密 jasypt 是一个简单易用的加解密Java库,可以快速集成到 Spring 项目中.可以快速集成到 Spring Boot 项 ...

  7. Git--gitLab远程仓库分支代码回退的两种方案

    事由:作为仓库的master,一时老眼昏花,把同事说的不合并看成了合并,直接合并了. 解决方法: 一.粗鲁的代码回退--直接在远程仓库合并 1. 在gitLab远程仓库中,基于想回退的代码的节点(co ...

  8. kettle 多表全删全插同步数据 两种方案

    背景: 接到上级指示,要从外网某库把数据全部导入到内网,数据每天更新一次即可,大约几百万条数据,两个库结构一样,mysql的,两台数据库所在服务器都是windows server的,写个java接口实 ...

  9. 基于VC++ Win32+CUDA+OpenGL组合与VC++ MFC SDI+CUDA+OpenGL组合两种方案的遥感影像显示:获得的重要结论!

    1.基于VC++ Win32+CUDA+OpenGL组合的遥感影像显示 在该组合方案下,初始化时将OpenGL设置为下面两种方式,效果一样 //设置方式1 glutInitDisplayMode (G ...

随机推荐

  1. 在WPF中使用AForge.net控制摄像头拍照

    原文:在WPF中使用AForge.net控制摄像头拍照 利用AForge.net控制摄像头拍照最方便的方法就是利用PictureBox显示摄像头画面,但在WPF中不能直接使用PictureBox.必须 ...

  2. python lcd 时间显示

    #!/usr/bin/python # QStopWatch -- a very simple stop watch # Copyright (C) 2006 Dominic Battre <d ...

  3. 5分钟精通git教程

    git是一个版本控制工具,就要先弄清楚什么是版本 版本: 对外发布的版本如v1.0.0,v1.1.0 叫version 内部代码的版本叫commit,如:修改了一个错别字 顾名思义一个version就 ...

  4. 使用markdown语法撰写csdn博客

    在CSDN之下写blog无疑是一件非常吃力的事情,对于非常多simple爱好者来讲,能用markdown语法来书写代码是最优雅简洁只是的了.本文主要介绍markdown语法和怎样它来撰写csdn下的b ...

  5. 事关Animation Tree的工作随笔(二)

    上回说到,游戏项目中客观会遇到逻辑状态的复杂性和动画状态的单一性之间的矛盾,那么Animation Tree是如何解决这个问题的呢? 这又需要引入一个定律:就是逻辑状态无论有多么复杂,但一套逻辑状态组 ...

  6. Swift 2.0初探:值得注意的新特性

    转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度的WWDC大会如期而至,在大会上A ...

  7. ibatis之##与$$的 使用

    /** 主要讲一下ibatis中$$的使用: 是为了传递参数; 参数一定在Action层用''包裹起来: */ List <SysRole> userList= systemService ...

  8. 常见HTTP状态码的含义

    200 请求已成功,请求所希望的响应头或数据体将随此响应返回. 301 被请求的资源已永久移动到新位置. 302 请求的资源现在临时从不同的 URI 响应请求. 400 1.语义有误,当前请求无法被服 ...

  9. 五种常见的ASP.NET应用程序安全缺陷

    下面给出了五个例子,阐述如何按照上述建议增强应用程序的安全性.这些例子示范了代码中可能出现的缺陷,以及它们带来的安全风险.如何改写最少的代码来有效地降低攻击风险.1 篡改参数◎ 使用ASP.NET域验 ...

  10. Asp.Net Mvc5新特性

    One ASP.NET:统一平台 BootStrap:免费Css响应式页面 路由标记属性:简单,控制器,操作,前缀,参数,URL ASP.NET WEB API 2:路由标记属性,Oauth2.0,O ...