Delphi直接读取XmL

来源:互联网 发布:测试本机端口是否开放 编辑:程序博客网 时间:2024/05/18 22:43

有时,只需要用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 0
原创粉丝点击