KORN Posted March 7, 2023 Share Posted March 7, 2023 Hi everyone ,How to I can read and update type file .config.xml from secition key and value. I have many machines. Previously I can create script read update only .ini , I can do but for .xml i don't know how. Please guide me or give me ideas. for my .xml as attched. Thank you FFIF_ProductSystemsSetting.config Link to comment Share on other sites More sharing options...
mistersquirrle Posted March 7, 2023 Share Posted March 7, 2023 (edited) I have used RegEx for some light XML parsing for some work related stuff, and as long as it's valid, it seems to work well (for me). It's just a couple functions: expandcollapse popup; <node ...> ... </node> Func GetNode($xml, $node, $exact = True) Local $sExact If $exact = True Then $sExact = '(?:>|\s+?.*?>)' Else $sExact = '.*?>' EndIf Return StringRegExp($xml, '(?s)(<' & $node & $sExact & '.*?</' & $node & '>)', 3) EndFunc ;==>GetNode ; <node ... /> Func GetNode2($xml, $node, $exact = True) Local $sExact If $exact = True Then $sExact = '(?:/>|\s+?.*?/>)' Else $sExact = '.*?>' EndIf Return StringRegExp($xml, '(?s)(<' & $node & $sExact & ')', 3) EndFunc ;==>GetNode2 ; <node ... attrib="xxx" ...> Func GetAttrib($xml, $node, $attrib, $exact = True) Local $sExact If $exact = True Then $sExact = '\s+?.*?' Else $sExact = '.*?' EndIf $result = StringRegExp($xml, '(?i)<' & $node & $sExact & $attrib & '="(.*?)".*?>', 3) If Not @error Then Return $result[0] Return '' EndFunc ;==>GetAttrib There may be some other solutions, such as something like this: However my only experience with XML in AutoIt has been with the couple of functions above. Also I suggest in the future that you post your code so that we can possibly select it to copy/paste and give it a shot ourselves: But, here's how I would use it to get the highlighted section of your code: expandcollapse popup#include <String.au3> Global $sXml = FileRead('FFIF_ProductSystemsSetting.config') ConsoleWrite('$sXml length: ' & StringLen($sXml) & @CRLF) Global $sConfigXml = GetNode($sXml, 'configuration', True) If IsArray($sConfigXml) Then $sConfigXml = $sConfigXml[0] ConsoleWrite('$sConfigXml length: ' & StringLen($sConfigXml) & @CRLF) Global $sHoltXml = GetNode($sConfigXml, 'HOLTRX3_VL') If IsArray($sHoltXml) Then $sHoltXml = $sHoltXml[0] ConsoleWrite('$sHoltXml length: ' & StringLen($sHoltXml) & @CRLF) Global $sCommonXml = GetNode($sHoltXml, 'Common') If IsArray($sCommonXml) Then $sCommonXml = $sCommonXml[0] ConsoleWrite('$sCommonXml length: ' & StringLen($sCommonXml) & @CRLF) Global $sFFSServerVersion = GetAttrib($sCommonXml, 'add key="FFSServer"', 'value') ConsoleWrite('FFSServer after traveling down the XML: ' & $sFFSServerVersion & @CRLF) ; Alternatively if there's just the one 'Common' node: $sCommonXml = GetNode($sXml, 'Common') If IsArray($sCommonXml) Then $sCommonXml = $sCommonXml[0] ConsoleWrite('$sCommonXml length from $sXml direct: ' & StringLen($sCommonXml) & @CRLF) ; And if there's only going to be one instance of FFSServer node: $sFFSServerVersion = GetAttrib($sXml, 'add key="FFSServer"', 'value') ConsoleWrite('$sXml direct: ' & $sFFSServerVersion & @CRLF) ; And then the possibly simpler approach: $sFFSServerVersion = _StringBetween($sXml, '"FFSServer" value="', '"') If Not @error Then $sFFSServerVersion = $sFFSServerVersion[0] ConsoleWrite('_StringBetween: ' & $sFFSServerVersion & @CRLF) EndIf ; <node ...> ... </node> Func GetNode($xml, $node, $exact = True) Local $sExact If $exact = True Then $sExact = '(?:>|\s+?.*?>)' Else $sExact = '.*?>' EndIf Return StringRegExp($xml, '(?s)(<' & $node & $sExact & '.*?</' & $node & '>)', 3) EndFunc ;==>GetNode ; <node ... /> Func GetNode2($xml, $node, $exact = True) Local $sExact If $exact = True Then $sExact = '(?:/>|\s+?.*?/>)' Else $sExact = '.*?>' EndIf Return StringRegExp($xml, '(?s)(<' & $node & $sExact & ')', 3) EndFunc ;==>GetNode2 ; <node ... attrib="xxx" ...> Func GetAttrib($xml, $node, $attrib, $exact = True) Local $sExact If $exact = True Then $sExact = '\s+?.*?' Else $sExact = '.*?' EndIf $result = StringRegExp($xml, '(?i)<' & $node & $sExact & $attrib & '="(.*?)".*?>', 3) If Not @error Then Return $result[0] Return '' EndFunc ;==>GetAttrib As you can see I accessed the data in a couple of ways, however the simplest way is probably going to be _StringBetween (https://www.autoitscript.com/autoit3/docs/libfunctions/_StringBetween.htm) or StringRegEx (https://www.autoitscript.com/autoit3/docs/functions/StringRegExp.htm) Edit: I missed the part about updating the XML, I haven't had a need to update an XML, so it again may be better to look into the XML UDF, or see if there's other solutions. Edited March 7, 2023 by mistersquirrle We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
KORN Posted March 7, 2023 Author Share Posted March 7, 2023 Thank you. I can read parameters from your script. How can I change 00.00.00.00 to xx.xx.xx.xx ? Link to comment Share on other sites More sharing options...
mistersquirrle Posted March 7, 2023 Share Posted March 7, 2023 I haven't had a need to update an XML, so it again may be better to look into the XML UDF, or see if there's other solutions. However, without doing it in a "proper" way, you could just use StringReplace: #include <FileConstants.au3> Global $sFile = 'FFIF_ProductSystemsSetting.config' Global $hFile = FileOpen($sFile, $FO_READ) If $hFile = -1 Then ConsoleWrite('Unable to open file for writing' & @CRLF) Exit EndIf Global $sXml = FileRead($hFile) FileClose($hFile) $sXml = StringReplace($sXml, '"FFSServer" value="00.00.00.00"', '"FFSServer" value="01.01.01.01"') $hFile = FileOpen($sFile, $FO_OVERWRITE) If $hFile = -1 Then ConsoleWrite('Unable to open file for writing' & @CRLF) Exit EndIf FileWrite($hFile, $sXml) FileClose($hFile) You could also use my simple little XML functions to get the current value for FFSServer and use that in your StringReplace: $sXml = StringReplace($sXml, '"FFSServer" value="' & $sValue & '"', '"FFSServer" value="01.01.01.01"') We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
KORN Posted March 7, 2023 Author Share Posted March 7, 2023 5 minutes ago, mistersquirrle said: I haven't had a need to update an XML, so it again may be better to look into the XML UDF, or see if there's other solutions. However, without doing it in a "proper" way, you could just use StringReplace: #include <FileConstants.au3> Global $sFile = 'FFIF_ProductSystemsSetting.config' Global $hFile = FileOpen($sFile, $FO_READ) If $hFile = -1 Then ConsoleWrite('Unable to open file for writing' & @CRLF) Exit EndIf Global $sXml = FileRead($hFile) FileClose($hFile) $sXml = StringReplace($sXml, '"FFSServer" value="00.00.00.00"', '"FFSServer" value="01.01.01.01"') $hFile = FileOpen($sFile, $FO_OVERWRITE) If $hFile = -1 Then ConsoleWrite('Unable to open file for writing' & @CRLF) Exit EndIf FileWrite($hFile, $sXml) FileClose($hFile) You could also use my simple little XML functions to get the current value for FFSServer and use that in your StringReplace: $sXml = StringReplace($sXml, '"FFSServer" value="' & $sValue & '"', '"FFSServer" value="01.01.01.01"') Appreciate for your help and give me for idea and example script. Link to comment Share on other sites More sharing options...
Nine Posted March 7, 2023 Share Posted March 7, 2023 By using XMLDOM object, you get way more control on your XML files. Here an example of how to use it : #include <Constants.au3> Local $oXML = ObjCreate("Microsoft.XMLDOM") $oXML.load("FFIF_ProductSystemsSetting.config") If $oXML.parseError.errorCode Then Exit MsgBox($MB_SYSTEMMODAL, "You have an error", $oXML.parseError.reason) Local $oFFS = $oXML.SelectSingleNode("//configuration/HOLTRX3_VL/Common/add[@key='FFSServer']") ConsoleWrite($oFFS.getAttribute('value') & @CRLF) $oFFS.setAttribute('value', '192.191.12.99') ConsoleWrite($oFFS.getAttribute('value') & @CRLF) $oXML.save("FFIF New.config") Complete reference is https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms764730(v=vs.85) “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
KORN Posted March 7, 2023 Author Share Posted March 7, 2023 12 minutes ago, Nine said: By using XMLDOM object, you get way more control on your XML files. Here an example of how to use it : #include <Constants.au3> Local $oXML = ObjCreate("Microsoft.XMLDOM") $oXML.load("FFIF_ProductSystemsSetting.config") If $oXML.parseError.errorCode Then Exit MsgBox($MB_SYSTEMMODAL, "You have an error", $oXML.parseError.reason) Local $oFFS = $oXML.SelectSingleNode("//configuration/HOLTRX3_VL/Common/add[@key='FFSServer']") ConsoleWrite($oFFS.getAttribute('value') & @CRLF) $oFFS.setAttribute('value', '192.191.12.99') ConsoleWrite($oFFS.getAttribute('value') & @CRLF) $oXML.save("FFIF New.config") Complete reference is https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms764730(v=vs.85) Thank you very much this is new knowledge for me. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now