• 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
  • 相关阅读:
    jQuery插件开发精品教程,让你的jQuery提升一个台阶
    Elasticsearch 更新和删除文档的过程
    Elasticsearch集群健康状态显示为yellow排查
    Golang官方包依赖管理工具 go mod
    Golang几种常用配置文件使用方法总结
    SQL高级功能:窗口函数
    MySQL经典50题
    MySQL 性能调优和系统资源优化解决方案
    【排序算法】堆排序的推导及实现
    增长策略:如何用AB测试进行活动评估及优化?
  • 原文地址:https://www.cnblogs.com/blogpro/p/11453546.html
Copyright © 2020-2023  润新知