有时,只需要用XML作一些小的应用,比如只是简单地保存日志或者一些配置,这时我们只需要直接读写XML就好,效率第一。
Delphi盒子有一个直接读写XML文件 (例子和代码),其核心函数为下面两个函数(一读一写):

{-------------------------------------------------------------------------------

Fun/Pro: GetXMLNodeValue

@Date: 2004.12.11

@Param: xmlFile xml文件

@Param: xmlnodepath 节点

@Param: xmlattrname 节点中的属性名称,如果直接取节点值则可以忽略此参数。

@Param: dep 节点的参数的分隔符,默认为.

@Return: 第一个节点的值

-------------------------------------------------------------------------------}

function GetXMLNodeValue(strEntityEngineFile:String; xmlNodePath:String;

const xmlattrname:String=''; const dep:Char ='.'):String;

var

xmlDocument :IXMLDocument;

node :IXMLNode;

xmlnodeList :TStrings;

i :Integer;

urlcount :Integer;

begin

//xml节点路径

xmlnodeList:=TStringList.Create;

xmlnodeList.Delimiter:=dep;

xmlnodeList.DelimitedText:=xmlnodepath;

urlcount:=xmlnodeList.Count;

//xml对象

xmlDocument :=TXMLDocument.Create(nil);

xmlDocument.LoadFromFile(strEntityEngineFile);

xmlDocument.Active:=true;

try

node:= xmlDocument.DocumentElement;

if(node.NodeName = xmlnodeList[]) then begin

//扫描节点

for i :=  to urlcount- do begin

if(node<>nil) then

node := getnodefromIXMLNodeList(node.ChildNodes,xmlnodeList[i])

else Break;

end;

if(node=nil)then begin

result:='';

end else begin

//判断是取属性还是取节点内容

if(Trim(xmlattrname)='') then

result:=node.Text

else

result:=node.AttributeNodes.Nodes[xmlattrname].NodeValue;

end;

end else begin

result:='';

end;

except

result:='error';

end;

xmlDocument.Active:=false;

end;

{-------------------------------------------------------------------------------

Fun/Pro: SetXMLNodeValue

@Date: 2004.12.11

@Param: xmlFile xml文件

@Param: xmlnodepath 节点

@Param: xmlattrname 节点中的属性名称,如果直接取节点值则可以忽略此参数。

@Param: dep 节点的参数的分隔符,默认为.

@Return: 操作成功否

-------------------------------------------------------------------------------}

function setXmlNodeValue(strEntityEngineFile:String; xmlNodePath:String;

const xmlattrname:String=''; const value:String=''; const dep:Char ='.'):boolean;

var

xmlDocument :IXMLDocument;

node :IXMLNode;

xmlnodeList :TStrings;

i :Integer;

urlcount :Integer;

begin

//xml节点路径

xmlnodeList:=TStringList.Create;

xmlnodeList.Delimiter:=dep;

xmlnodeList.DelimitedText:=xmlnodepath;

urlcount:=xmlnodeList.Count;

//xml对象

xmlDocument :=TXMLDocument.Create(nil);

xmlDocument.LoadFromFile(strEntityEngineFile);

xmlDocument.Active:=true;

try

node:= xmlDocument.DocumentElement;

if(node.NodeName = xmlnodeList[]) then begin

//扫描节点

for i :=  to urlcount- do begin

if(node<>nil) then

node := getnodefromIXMLNodeList(node.ChildNodes,xmlnodeList[i])

else Break;

end;

if(node <> nil)then begin

if(Trim(xmlattrname)='') then

node.Text:=value

else

node.AttributeNodes.Nodes[xmlattrname].NodeValue:=value;

xmlDocument.SaveToFile(strEntityEngineFile);

end;

end;

result:=true;

except

result:=false;

end;

xmlDocument.Active:=false;

end;

但是上述两个函数有一个问题:它只能按节点名和属性名查找第一条记录。举例:如果要操作类似下述XML文件,节点和属性名相同的有多个,只是属性的值不一样,上面的读写函数就罢工了。

<colour name="normal attribute" red="" green="" blue=""/>

<colour name="good attribute" red="" green="" blue=""/>

<colour name="excellent attribute" red="" green="" blue=""/>

OK,程序员的最大乐趣就是自己动手了。我们来改造一下这两个函数。
在原有函数的基础上增加了两个参数: function TOperateXml.getnodefromIXMLNodeList(childnodes: IXMLNodeList; nodename: string):
IXMLNode;
var
i: Integer;
begin
for i := to childnodes.Count do
begin
if (childnodes.Get(i - ).NodeName = nodename) then
begin
result := childnodes[i - ];
exit;
end;
end;
end; {------------------------------------------------------------------------------- Fun/Pro: GetXMLNodeSpecialValue @Date: 2004.12.11 @Param: xmlFile xml文件 @Param: xmlnodepath 节点 @Param: xmlattrname 节点中的属性名称,如果直接取节点值则可以忽略此参数。 @Param: XMLSpecialName 要查找的节点中属性名 @Param: XMLSpecialValue 要查找的节点中某属性对应的值 @Param: dep 节点的参数的分隔符,默认为. @Return: 某属性的值 -------------------------------------------------------------------------------} function GetXMLNodeSpecialValue(strEntityEngineFile:String; XMLNodePath:String; const XMLAttrName:String=''; const XMLSpecialName:String=''; const XMLSpecialValue:String=''; const dep:Char ='.'):String; var xmlDocument :IXMLDocument; node :IXMLNode; xmlnodeList :TStrings; i :Integer; urlcount :Integer; begin //xml节点路径 xmlnodeList:=TStringList.Create; xmlnodeList.Delimiter:=dep; xmlnodeList.DelimitedText:=xmlnodepath; urlcount:=xmlnodeList.Count; //xml对象 xmlDocument :=TXMLDocument.Create(nil); xmlDocument.LoadFromFile(strEntityEngineFile); xmlDocument.Active:=true; try node:= xmlDocument.DocumentElement; if(node.NodeName = xmlnodeList[]) then begin //扫描节点 for i := to urlcount- do begin if(node<>nil) then begin node := getnodefromIXMLNodeList(node.ChildNodes,xmlnodeList[i]); end else Break; end; if(node=nil)then begin result:=''; end else begin //判断是取属性还是取节点内容 if(Trim(xmlattrname)='') then result:=node.Text else begin result := node.AttributeNodes.Nodes[XMLSpecialName].NodeValue; //这里不想再声明一个临时变量了,就用result来比较,可能有隐患。 while ((result <> XMLSpecialValue)) do begin node := node.NextSibling; while (node.NodeName = '#comment') do begin node:= node.NextSibling; end; result := node.AttributeNodes.Nodes[XMLSpecialName].NodeValue; end; result:=node.AttributeNodes.Nodes[XMLAttrName].NodeValue; end; end; end else begin result:=''; end; except result:='error'; end; xmlDocument.Active:=false; end; 写函数 {------------------------------------------------------------------------------- Fun/Pro: SetXMLNodeSpecialValue @Date: 2004.12.11 @Param: xmlFile xml文件 @Param: xmlnodepath 节点 @Param: xmlattrname 节点中的属性名称,如果直接取节点值则可以忽略此参数。 @Param: XMLSpecialName 要查找的节点中属性名 @Param: XMLSpecialValue 要查找的节点中某属性对应的值 @Param: dep 节点的参数的分隔符,默认为. @Return: 操作成功与否 -------------------------------------------------------------------------------} function SetXMLNodeSpecialValue(strEntityEngineFile:String; xmlNodePath:String; const xmlattrname:String=''; const value:String=''; const XMLSpecialName:String=''; const XMLSpecialValue:String=''; const dep:Char ='.'):boolean; var xmlDocument :IXMLDocument; node :IXMLNode; xmlnodeList :TStrings; i :Integer; urlcount :Integer; CMPValue :String; begin //xml节点路径 xmlnodeList:=TStringList.Create; xmlnodeList.Delimiter:=dep; xmlnodeList.DelimitedText:=xmlnodepath; urlcount:=xmlnodeList.Count; //xml对象 xmlDocument :=TXMLDocument.Create(nil); xmlDocument.LoadFromFile(strEntityEngineFile); xmlDocument.Active:=true; try node:= xmlDocument.DocumentElement; if(node.NodeName = xmlnodeList[]) then begin //扫描节点 for i := to urlcount- do begin if(node<>nil) then node := getnodefromIXMLNodeList(node.ChildNodes,xmlnodeList[i]) else Break; end; if(node <> nil)then begin {if(Trim(xmlattrname)='') then node.Text:=value else node.AttributeNodes.Nodes[xmlattrname].NodeValue:=value; } if (Trim(XMLAttrName)='') then node.Text := value else begin CMPValue := node.AttributeNodes.Nodes[XMLSpecialName].NodeValue; while (CMPValue <> XMLSpecialValue) do begin node := node.NextSibling; while (node.NodeName = '#comment') do begin node:= node.NextSibling; end; CMPValue := node.AttributeNodes.Nodes[XMLSpecialName].NodeValue; end; node.AttributeNodes.Nodes[XMLAttrName].NodeValue:=value; end; xmlDocument.SaveToFile(strEntityEngineFile); end; end; result:=true; except result:=false; end; xmlDocument.Active:=false; end;

Delphi直接读取XmL的更多相关文章

  1. Delphi中解析Xml的控件-SimDesign NativeXml

    Delphi中解析Xml的控件-SimDesign NativeXml 正在学习,感觉应用很方便.无源代码的版本还是免费的. SimDesign.NativeXml是一个delphi和bcb的XML控 ...

  2. 读取xml数据装配到字典中之应用场景

    前段时间看到支付宝设置里面有个多语言这个功能,蛮有意思的,就想双休没事的话做个相关的demo玩玩,可是礼拜六被妹子拽出去玩了一天,来大上海有大半年了,基本没有出去玩过,妹子说我是超级宅男,也不带她出去 ...

  3. 自己动手之使用反射和泛型,动态读取XML创建类实例并赋值

    前言: 最近小匹夫参与的游戏项目到了需要读取数据的阶段了,那么觉得自己业余时间也该实践下数据相关的内容.那么从哪入手呢?因为用的是Unity3d的游戏引擎,思来想去就选择了C#读取XML文件这个小功能 ...

  4. MFC如何读取XML

    <?xml version="1.0" encoding="utf-8"?> <Cases> <case> <No&g ...

  5. 使用dom4j读取xml连接数据库与之单例模式

    使用dom4j读取xml ,加入jar包 dom4j-1.6.1.jar jaxen-1.1-beta-6.jar public class XmlConfigReader { //懒汉式,延迟加载 ...

  6. java DOM4J 读取XML

    最近学习Java,在处理XML文档的时候,查阅相关资料,发现了DOM4J这个jre库,相对C#的XML处理来说,功能还算是跟得上 下面展示一篇我自己写的一个XML读取测试 import java.ut ...

  7. C#中常用的读取xml的几种方法(转)

    本文完全来源于http://blog.csdn.net/tiemufeng1122/article/details/6723764,仅作个人学习之用. XML文件是一种常用的文件格式,例如WinFor ...

  8. wcf序列化大对象时报错:读取 XML 数据时,超出最大

    错误为: 访问服务异常:格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出 错: request.InnerException 消息是“反序 ...

  9. C#中常用的几种读取XML文件的方法

    1.C#中常用的几种读取XML文件的方法:http://blog.csdn.net/tiemufeng1122/article/details/6723764/

随机推荐

  1. C# 简单软件有效期注册的实现

    ◆需求:公司一直以来对开发的产品都没有进行使用时间的控制,要么就是将日期限制写死在程序里面,每次都要编译新程序再发给客户,很不方便.于是公司让我写个模块,要求如下:1.无论哪个新开发的程序只要调用这个 ...

  2. 4 November in ss

    Contest A. 输油管道问题 某石油公司计划建造一条由东向西的主输油管道.该管道要穿过一个有 \(n\) 口油井的油田.从每口油井都要有一条输油管道沿最短路经 (或南或北) 与主管道相连.如果给 ...

  3. (转)VirtualBox下安装CentOS7系统

    转:https://www.cnblogs.com/hihtml5/p/8217062.html 本文假定你已经知道如何安装VirtualBox虚拟机软件,并且已经安装好了. 首先我们需要准备好cen ...

  4. UE编辑器

    引用ue的js 下载地址http://pan.baidu.com/s/1gdrQ35L <script type="text/javascript" src="__ ...

  5. SetWindowsHookEx 其他进程的 记录

    SetWindowsHookEx(  WH_GETMESSAGE,CallWndProc, HInstance, h2); WH_GETMESSAGE  这个类型 hook  其他窗体的 线程是正常的 ...

  6. git使用记录九:开发中临时加塞了紧急任务怎么处理

    开发中临时加塞了紧急任务怎么处理 隐藏工作区域 git stash git status 查询隐藏的列表 git stash list 处理完bug,提交之后,再恢复隐藏的工作区域 git stash ...

  7. 2019 SCUT SE 新生训练第四波 L - Boxes in a Line——双向链表

    先上一波题目 https://vjudge.net/contest/338760#problem/L 这道题我们维护一个双向链表 操作1 2 3 都是双向链表的基本操作 4操作考虑到手动将链表反转时间 ...

  8. Oracle数据库(一)--Oracle简介及安装

    一.Oracle简介 Oracle是美国一家著名的软件公司,也是世界上排名前三的软件公司(微软,Oracle,Adobe).Oracle数据库是一个大型的关系型数据库,在一些大型的企业之中使用的会比较 ...

  9. asciinema.org -Record Your Terminal Share it with no fuss

    紀錄 Terminal 下指令的過程 http://asciinema.org/

  10. 图片查看器(类似于QQ,另外又加了JARA的下方的图片缩略导航图)

    源码地址:https://gitee.com/yolanda624/coffer/tree/master/src/components/a-photo-view