Delphi之通过代码示例学习XML解析、StringReplace的用法(异常控制 good)
*Delphi之通过代码示例学习XML解析、StringReplace的用法
这个程序可以用于解析任何合法的XML字符串。
首先是看一下程序的运行效果:
以解析这样一个XML的字符串为例:
<?xml version="1.0" encoding="UTF-8"?><BookInfo><Owner><OwnerName>张三</OwnerName><OwnerAge>1234</OwnerAge></Owner><BookMes><BookName>时间简史</BookName><ISDN>234343453534</ISDN><Writer>霍金</Writer></BookMes></BookInfo>
首先是打开应用程序

然后将上面所示的字符串复制到文本编辑框中,然后点击解析按钮,会出现下面的效果

如上图所示,可以 “XML中的字段标签:XML中对应标签的值” 的格式显示解析的效果。
因为进行了异常处理(使用try..except..end,并且在异常处理中使用ShowMessage弹出异常信息),所以如果输入的字符串不是合法的XML格式的话,程序会正常报错,而不会异常终止。
比如没有输入直接点击解析按钮,效果如下:

有比如输入一个非法的字符串,效果如下

然后看一下代码
|
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
|
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, XMLIntf, XMLDoc;type TForm1 = class(TForm) edt1: TEdit; btn1: TButton; procedure btn1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure ReadXml(Node: IXMLNode; var showmess: string);var NodeList: IXMLNodeList; strName: string; i: Integer;begin if not Node.HasChildNodes then Exit; nodeList := node.ChildNodes; for i := 0 to nodeList.Count - 1 do begin strName := nodeList[i].NodeName; if nodeList[i].IsTextElement then //如果是元素 begin showmess:= showmess + strName + ':' + NodeList[i].NodeValue + #13#10; end else if nodeList[i].HasChildNodes then //如果有子节点 begin ReadXml(NodeList[i], showmess); end; end;end;procedure TForm1.btn1Click(Sender: TObject);var sXML, showmess: string; ComInstrXML: IXMLDocument; mainNode: IXMLNode;begin showmess:= ''; sXML:= edt1.Text; sXML:= StringReplace(sXML, 'UTF-8', 'gbk', []); //只替换<?xml version="1.0" encoding="UTF-8"?>里面的字符编码方式,因为往往这个是在最前面出现的,所以StringReplace的第四个参数是[] try //一定不要忘记异常处理,保证程序的稳定性,能够正常处理异常而不至于在发生异常的时候导致程序崩溃 ComInstrXML:= LoadXMLData(sXML); mainNode:= ComInstrXML.DocumentElement; readXML(mainNode, showmess); ShowMessage(showmess); except on E: Exception do begin ShowMessage(E.Message); end; end;end;end. |
讲解一下代码
0.建议这样使用XML解包
本例中的程序,在解包之后是将标签以及对应的值显示在弹出框上,这样只是为了演示解析XML的效果。
建议在开发中将解析好的XML节点,以节点的标签作为Key,以节点的内容作为value,插入到一个可以搜索的链表或者其他什么可以根据Key进行搜索的容器类中,然后在之后使用的时候就可以很方便的搜索到解析后的值。
1.注意解析XML使用到相关的类、方法所属的单元
要使用IXMLDocument、IXMLNodeList和iXMLNode,需要引入 XMLIntf 单元。
要使用 LoadXMLData方法,需要引入XMLDoc 单元。
2.递归解包XML
因为XML本身就是一个递归的结构,所以解包XML,也就是其中的ReadXML 方法使用的就是递归的方法,递归结束标志是:正在解析的XML标签是一个元素,没有子节点。
3.字符编码的问题
在 TForm1.btn1Click(Sender: TObject) 方法中,我们可以看到首先将XML字符串中的 'UTF-8' 替换为 'gbk',因为如果编码方式是UTF-8:<?xml version="1.0" encoding="UTF-8"?>,那么如果XML中存在中文,那么解析的时候会报错(如果全部为英文,那么就不会报错),如下图

如果将UTF-8替换为gbk,,那么在解析XML的时候就不会报这样的错误。
另外如果以不包含编码格式的XML字符串,如:<BookInfo><Owner><OwnerName>张三</OwnerName><OwnerAge>1234</OwnerAge></Owner><BookMes><BookName>时间简史</BookName><ISDN>234343453534</ISDN><Writer>霍金</Writer></BookMes></BookInfo>,没有 <?xml version="1.0" encoding="UTF-8"?>的话,此时就算有 sXML:= StringReplace(sXML, 'UTF-8', 'gbk', [rfReplaceAll]); 这样的替换字符编码的代码也是没有用的,也没有办法改成gbk的编码,所以仍然会报上面的异常。
所以请注意字符编码的问题,尤其是既有中文又有英文的时候。
另外还有一个需要注意的点,我们只需要替换“<?xml version="1.0" encoding="UTF-8"?>”这个里面的UTF-8为gbk就行了,因为可能XML本身的其他字段就存储着什么关于字符编码的信息,但是与本条XML报文无关,纯粹只是一条需要传输的信息。下面的一条XML的报文就是例子:
<?xml version="1.0" encoding="UTF-8"?><BookInfo><Charset>UTF-8</Charset><Owner><OwnerName>张三</OwnerName><OwnerAge>1234</OwnerAge></Owner><BookMes><BookName>时间简史</BookName><ISDN>234343453534</ISDN><Writer>霍金</Writer></BookMes></BookInfo>
这时候在替换的时候,要注意只要替换XML本身的字符编码就好了,其他的XML需要传输的可能有关于字符编码的信息不能替换,否则可能导致传输的XML信息违背了其传输时候的初衷了!!
所以上面的代码中使用:sXML:= StringReplace(sXML, 'UTF-8', 'gbk', []); 其中StringReplace的第四个参数是[] 表示只替换第一个即可。
4.stringReplace函数的使用
function StringReplace (const S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string;
rfReplaceAll:全部替换
rfIgnoreCase:忽略大小写
例子
|
1
2
3
4
5
6
7
8
9
10
|
var aStr: String;begin aStr := 'This is a book, not a pen!'; ShowMessage(StringReplace (aStr, 'a', 'two', []));//This is two book, not a pen!只替换了第一个符合的字符串 ShowMessage(StringReplace (aStr, 'a', 'two', [rfReplaceAll]));//This is two book, not two pen!替换了所有符合的字符串 aStr := 'This is a book, not A pen!'; ShowMessage(StringReplace (aStr, 'a', 'two', [rfReplaceAll]));//This is two book, not A pen!只替换了符合的字符串(小写a) ShowMessage(StringReplace (aStr, 'a', 'two', [rfReplaceAll, rfIgnoreCase]));//This is two book, not two pen!不管大小写替换了所有符合的字符串end; |
5.换行
注意代码中有这样一行代码:
|
1
|
showmess:= showmess + strName + ':' + NodeList[i].NodeValue + #13#10; |
其中的 #13#10 表示换行
http://www.cnblogs.com/xumenger/p/4711223.html
Delphi之通过代码示例学习XML解析、StringReplace的用法(异常控制 good)的更多相关文章
- Delphi之通过代码示例学习XML解析、StringReplace的用法
这个程序可以用于解析任何合法的XML字符串. 首先是看一下程序的运行效果: 以解析这样一个XML的字符串为例: <?xml version="1.0" encoding=&q ...
- iOS开发之网络数据解析(二)--XML解析简介
前言:本篇随笔介绍的是XML解析. 正文: 1.XML解析方式有2两种: DOM:一次性将整个XML数据加载进内存进行解析,比较适合解析小文件 SAX:从根元素开始,按顺序一个元素一个元素往下解析,比 ...
- Python XML 解析
什么是 XML? XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. XML 是一套定义语义标记的规则,这些标记将文档分成许多部件并 ...
- XML解析与xml和Map集合的互转
1.XML的解析.首先解析XML文件我们需要先获取到文件的存放路径,获取方法有三种分别获取xml文件不同的存放路径. 代码: public class PropertiesDemo { public ...
- Spring 注解学习 详细代码示例
学习Sping注解,编写示例,最终整理成文章.如有错误,请指出. 该文章主要是针对新手的简单使用示例,讲述如何使用该注释,没有过多的原理解析. 已整理的注解请看右侧目录.写的示例代码也会在结尾附出. ...
- IOS学习:常用第三方库(GDataXMLNode:xml解析库)
IOS学习:常用第三方库(GDataXMLNode:xml解析库) 解析 XML 通常有两种方式,DOM 和 SAX: DOM解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过 ...
- 分享用于学习C++音频处理的代码示例
与<分享用于学习C++图像处理的代码示例>为姊妹篇. 为了便于学习C++音频处理并研究音频算法, 俺写了一个适合初学者学习的小小框架. 麻雀虽小五脏俱全,仅仅考虑单通道处理. 采用Deco ...
- javaweb学习总结十(xml解析<SAX以及DOM方式>)
一:XML解析技术 一般我们使用sun公司或者开源组织开发的工具包解析xml效率比较高. 1:jaxp解析xml,jaxp是sun公司开发的解析xml工具包 2:jaxp解析xml代码如下 a:获取d ...
- android学习日记23--Android XML解析
一.简述 XML语言是跨平台,JAVA对XML语言支持得比较好,android系统的应用层平台是JAVA做的,所以用XML.XML解析比较简单.XML解析就是将获取到的数据分离出来,基本的网络数据传输 ...
随机推荐
- Min and Max
Min and Max 需要处理不同数据类型; 另外*args, 表示的是位置参数, *kwargs表示的是key参数, args的类型为tuple类型, 参数为min(3, 2)时, args为(3 ...
- (转载):() { :|:& }; : # <-- 打开终端,输入这个,回车.你看到了什么??
代码::() { :|:& }; : 为什么这个东西会让你的系统死掉???有人执行了然后问我 让我们来分析一下这段代码,我改一下格式,但内容是一样的 代码::() # 定义一个叫“:”的过程 ...
- sql server数据建表
use edudbgoif exists(select * from sysobjects where name='department')drop table departmentcreate ta ...
- 优化C#程序的48种方法
一.用属性代替可访问的字段 1..NET数据绑定只支持数据绑定,使用属性可以获得数据绑定的好处: 2.在属性的get和set访问器重可使用lock添加多线程的支持. 二.readonly(运行时常量) ...
- back_insert_iterator和iterator用起来不一样。
先看代码: #include<iostream> #include<vector> #include<algorithm> #include<iterator ...
- softlayerFastUploadVHDtoBS
Object Storage Uploader Overview We’ve recently added the option to import customer-supplied Virtual ...
- Spring MVC基础
1.Web MVC基础 MVC的本质是表现层模式,我们以视图模型为中心,将视图和控制器分离出来.就如同分层模式一样,我们以业务逻辑为中心,把表现层和数据访问层代码分离出来是一样的方法.框架只能在技术层 ...
- jQuery插件Jeditable的使用(Struts2处理)
Jeditable - Edit In Place Plugin For jQuery,是一款JQuery就地编辑插件.也就是在页面直接点击需要编辑的内容,就会自动变成文本框进行编辑.它的官方 ...
- fragment的入门DEMO
效果图: 代码如下: 1.main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay ...
- 百度地图 Android SDK - 检索功能使用的简单演示样例
百度地图 SDK 不仅为广大开发人员提供了炫酷的地图展示效果.丰富的覆盖物图层,更为广大开发人员提供了多种 LBS 检索的能力. 通过这些接口,开发人员能够轻松的訪问百度的 LBS 数据,丰富自己的移 ...