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

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值