有时,只需要用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. element菜单默认展开和选中

    这两个属性, :default-openeds="openeds" default-active="/networkConfig"中设置的要与数组中的index ...

  2. redis哨兵-5

    #地址: https://www.cnblogs.com/PatrickLiu/p/8444546.html #常用架构 redis1主1从+3哨兵 实现redis高可用 #redis主从 ##### ...

  3. iOS 获取全局唯一标示符

    这个方法用来产生一个唯一的标示符,每次调用都会不一样,所以可以用当作一些临时缓存文件的名字 NSString *identifier = [[NSProcessInfo processInfo] gl ...

  4. JS基础入门篇(四)—this的使用,模拟单选框,选项卡和复选框

    1.this的使用 this js中的关键字 js内部已经定义好了,可以不声明 直接使用 this的指向问题 1. 在函数外部使用 this指向的是window 2. 在函数内部使用 有名函数 直接调 ...

  5. MySQL查询缓存详解(总结)

    MySQL查询缓存详解(总结) 一.总结 一句话总结: mysql查询缓存还是可以用用试一试,但是更推荐分布式,比如redis/memcache之流,将数据库中查询的数据和查询语句以键值对的方式存进分 ...

  6. android 关联某些后缀使用app打开

    <intent-filter> <action android:name="android.intent.action.VIEW" /> <categ ...

  7. dex2jar反编译大文件内存溢出的问题

    @echo off REM better invocation scripts for windows from lanchon, release in public domain. thanks! ...

  8. python使用消息队列RabbitMq(进阶)

    import pika connection = pika.BlockingConnection(pika.ConnectionParameters( 'localhost')) channel = ...

  9. 【题解】Antisymmetry

    题目大意 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串.比如00001111和010101就是反对称的,1001就不是. 现在给出一个长度为N的 ...

  10. [Python]判断序列是否为空的正确姿势

    本篇文章起源于StackOverflow上一个热度非常高的问题: 我该如何判断一个Python列表是否为空? @Ray Vega (提问者) 举例说明,现在我得到了如下代码: a = [] 我如何该检 ...