Delphi直接读取XmL

有时,只需要用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[0]) then begin

//扫描节点

for i := 1 to urlcount-1 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[0]) then begin

//扫描节点

for i := 1 to urlcount-1 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="100" green="125" blue="150"/>

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

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

OK,程序员的最大乐趣就是自己动手了。我们来改造一下这两个函数。 
在原有函数的基础上增加了两个参数:

function TOperateXml.getnodefromIXMLNodeList(childnodes: IXMLNodeList; nodename: string): 
IXMLNode; 
var 
i: Integer; 
begin 
for i := 1 to childnodes.Count do 
begin 
if (childnodes.Get(i - 1).NodeName = nodename) then 
begin 
result := childnodes[i - 1]; 
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[0]) then begin

//扫描节点

for i := 1 to urlcount-1 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[0]) then begin

//扫描节点

for i := 1 to urlcount-1 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;
View Code
原文地址:https://www.cnblogs.com/blogpro/p/11453546.html