• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Delphi直接读写XML修改版

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

有时,只需要用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; 
 
 
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人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi中的接口和抽象类发布时间:2022-07-18
下一篇:
Delphi获得与设置系统时间格式《转》发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap