Sometimes, we only need to use XML as some small applications, such as simply saving logs or some configurations. At this time, we only need to read and write XML directly, efficiency is the first priority. The Delphi box has a direct read and write XML file (examples and code), and its core function is the following two functions (one read and one write):
{------------------------------------------------- ------------------------------Fun/PRo:GetXMLNodeValue@Date:2004.12.11@Param:xmlFilexml文件@Param:xmlnodepath Node @Param:xmlarattrname attribute name in node. If you directly take the node value, this parameter can be ignored. @Param: The delimiter of the parameters of the dep node, default is .@Return: The value of the first node ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- --}functionGetXMLNodeValue(strEntityEngineFile:String;xmlNodePath:String;constxmlattrname:String='';constdep:Char='.'):String;varxmlDocument:IXMLDocument;node:IXMLNode;xmlnodeList:TStrings;i:Integer;urlcount:Integer ;begin//xml node path xmlnodeList:=TStringList.Create;xmlnodeList.Delimiter:=dep;xmlnodeList.DelimitedText:=xmlnodepath;urlcount:=xmlnodeList.Count;//xml object xmlDocument:=TXMLDocument.Create(nil);xmlDocument .LoadFromFile(strEntityEngineFile);xmlDocument.Active:=true;trynode:=xmlDocument.DocumentElement;if(node.NodeName=xmlnodeList[0])thenbegin//Scan node fori:=1tourlcount-1dobeginif(node<>nil)thennode: =getnodefromIXMLNodeList(node.ChildNodes,xmlnodeList[i])elseBreak;end;if(node=nil)thenbeginresult:='';endelsebegin//Judge whether to take attributes or node content if(Trim(xmlattrname)='')thenresult :=node.Textelseresult:=node.AttributeNodes.Nodes[xmlattrname].NodeValue;end;endelsebeginresult:='';end;exceptresult:='error';end;xmlDocument.Active:=false;end;end;{--- -------------------------------------------------- ------------------------------Fun/Pro:SetXMLNodeValue@Date:2004.12.11@Param:xmlFilexml file@Param:xmlnodepath node@Param: The attribute name in the xmlattrname node. If you directly take the node value, you can ignore this parameter. @Param: The delimiter of the parameters of the dep node, default is .@Return: No operation is successful --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------} functionsetXmlNodeValue(strEntityEngineFile:String;xmlNodePath:String;constxmlattrname:String='';constvalue:String='';constdep:Char='.'):boolean;varxmlDocument:IXMLDocument;node:IXMLNode;xmlnodeList:TStrings;i:Integer ;urlcount:Integer;begin//xml node path xmlnodeList:=TStringList.Create;xmlnodeList.Delimiter:=dep;xmlnodeList.DelimitedText:=xmlnodepath;urlcount:=xmlnodeList.Count;//xml object xmlDocument:=TXMLDocument.Create( nil);xmlDocument.LoadFromFile(strEntityEngineFile);xmlDocument.Active:=true;trynode:=xmlDocument.DocumentElement;if(node.NodeName=xmlnodeList[0])thenbegin//Scan node fori:=1tourlcount-1dobeginif(node<> nil)thennode:=getnodefromIXMLNodeList(node.ChildNodes,xmlnodeList[i])elseBreak;end;if(node<>nil)thenbeginif(Trim(xmlattrname)='')thennode.Text:=valueelsenode.AttributeNodes.Nodes[xmlattrname] .NodeValue:=value;xmlDocument.SaveToFile(strEntityEngineFile);end;end;result:=true;exceptresult:=false;end;xmlDocument.Active:=false;end;But there is a problem with the above two functions: it can only find the first record by node name and attribute name. For example: If you want to operate an XML file similar to the following, there are multiple nodes and attribute names with the same attribute names, but the values of the attributes are different, and the above read and write functions will go on strike.
<colourname=normalattributed=100green=125blue=150/><colourname=goodattributed=150green=175blue=200/><colourname=Excellentattributed=0green=0blue=255/>OK, the greatest pleasure for programmers is to do it yourself. Let's revise these two functions. Two parameters are added to the original function:
{------------------------------------------------- -----------------------------------------------Fun/Pro:GetXMLNodeSpecialValue@Date:2004.12.11@Param:xmlFilexml file@Param:xmlnodepath Node @Param:xmlarattrname attribute name in node. If you directly take the node value, this parameter can be ignored. @Param: The attribute name in the node to be searched for by XMLSpecialName @Param:XMLSpecialValue The value corresponding to a certain attribute in the node to be searched for @Param:dep node's parameter separator, default is .@Return: The value of a certain attribute--- -------------------------------------------------- -------------------------}functionGetXMLNodeSpecialValue(strEntityEngineFile:String;XMLNodePath:String;constXMLAttrName:String='';constXMLSpecialName:String=''; constXMLSpecialValue:String='';constdep:Char='.'):String;varxmlDocument:IXMLDocument;node:IXMLNode;xmlnodeList:TStrings;i:Integer;urlcount:Integer;begin//xmlnode path xmlnodeList:=TStringList.Create ;xmlnodeList.Delimiter:=dep;xmlnodeList.DelimitedText:=xmlnodepath;urlcount:=xmlnodeList.Count;//xml object xmlDocument:=TXMLDocument.Create(nil);xmlDocument.LoadFromFile(strEntityEngineFile);xmlDocument.Active:=true; trynode:=xmlDocument.DocumentElement;if(node.NodeName=xmlnodeList[0])thenbegin//Scan node fori:=1tourlcount-1dobeginif(node<>nil)thenbeginnode:=getnodefromIXMLNodeList(node.ChildNodes,xmlnodeList[i]); endelseBreak;end;if(node=nil)thenbeginresult:='';endelsebegin//Judge whether to take attributes or node content if(Trim(xmlarattrname)='')thenresult:=node.Textelsebeginresult:=node.AttributeNodes.Nodes [XMLSpecialName].NodeValue;//I don’t want to declare a temporary variable here, so I use result to compare, which may be hidden dangers. while((result<>XMLSpecialValue))dobeginnode:=node.NextSibling; while(node.NodeName='#comment')dobeginnode:=node.NextSibling; end;result:=node.AttributeNodes.Nodes[XMLSpecialName].NodeValue; end;result:=node.AttributeNodes.Nodes[XMLAttrName].NodeValue;end;end;end;endelsebeginresult:='';end;exceptresult:='error';end;xmlDocument.Active:=false;end;Write functions
{------------------------------------------------- -----------------------------------------Fun/Pro:SetXMLNodeSpecialValue@Date:2004.12.11@Param:xmlFilexml file@Param:xmlnodepath Node @Param:xmlarattrname attribute name in node. If you directly take the node value, this parameter can be ignored. @Param: The attribute name in the node to be searched for by XMLSpecialName @Param:XMLSpecialValue The value corresponding to a property in the node to be searched for by @Param:dep node parameter separator, default is .@Return: Is the operation successful or not--- -------------------------------------------------- -------------------------}functionSetXMLNodeSpecialValue(strEntityEngineFile:String;xmlNodePath:String;constxmlattrname:String='';constvalue:String=''; constXMLSpecialName:String='';constXMLSpecialValue:String='';constdep:Char='.'):boolean;varxmlDocument:IXMLDocument;node:IXMLNode;xmlnodeList:TStrings;i:Integer;urlcount:Integer;CMPValue:String;begin //xml node path xmlnodeList:=TStringList.Create;xmlnodeList.Delimiter:=dep;xmlnodeList.DelimitedText:=xmlnodepath;urlcount:=xmlnodeList.Count;//xml object xmlDocument:=TXMLDocument.Create(nil);xmlDocument.LoadFromFile (strEntityEngineFile);xmlDocument.Active:=true;trynode:=xmlDocument.DocumentElement;if(node.NodeName=xmlnodeList[0])thenbegin//Scan node fori:=1tourlcount-1dobeginif(node<>nil)thennode:=getnodefromIXMLNodeList (node.ChildNodes,xmlnodeList[i])elseBreak;end;if(node<>nil)thenbegin{if(Trim(xmlattrname)='')thennode.Text:=valueelsenode.AttributeNodes.Nodes[xmlattrname].NodeValue:= value;}if(Trim(XMLAttrName)='')thennode.Text:=valueelsebeginCMPValue:=node.AttributeNodes.Nodes[XMLSpecialName].NodeValue; while(CMPValue<>XMLSpecialValue)dobeginnode:=node.NextSibling; while(node. NodeName='#comment')dobeginnode:=node.NextSibling;end;CMPValue:=node.AttributeNodes.Nodes[XMLSpecialName].NodeValue;end;node.AttributeNodes.Nodes[XMLAttrName].NodeValue:=value;end;xmlDocument. SaveToFile(strEntityEngineFile);end;end;result:=true;exceptresult:=false;end;xmlDocument.Active:=false;end;