zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Maximum Depth of Binary Tree
    Single Number
    Merge Two Sorted Lists
    Remove Nth Node From End of List
    Remove Element
    Remove Duplicates from Sorted List
    Add Two Numbers
    编译视频直播点播平台EasyDSS数据排序使用Go 语言 slice 类型排序的实现介绍
    RTMP协议视频直播点播平台EasyDSS在Linux系统中以服务启动报错can’t evaluate field RootPath in type*struct排查
    【解决方案】5G时代RTMP推流服务器/互联网直播点播平台EasyDSS实现360°全景摄像机VR直播
  • 原文地址:https://www.cnblogs.com/blogpro/p/11453546.html
Copyright © 2011-2022 走看看