MadBoy Posted August 22, 2007 Share Posted August 22, 2007 (edited) Can anyone help me with this XML problem. I wrote little function that i use to create temp .xml file and it seems that when the first value always gets written properly, the 2nd one doesn't. expandcollapse popup#Include <_XMLDomWrapper.au3> Global $settings_temporary = @ScriptDir & "\post_deployment_temporary.xml" If RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system", "legalnoticetext") <> "" Then _TempXMLSetting("legalnoticetext", RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system", "legalnoticetext"), "write") If RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system", "legalnoticecaption") <> "" Then _TempXMLSetting("legalnoticecaption", RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system", "legalnoticecaption"), "write") If _TempXMLSetting("legalnoticecaption", "", "read") <> "" Then MsgBox(0,"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system - legalnoticecaption", _TempXMLSetting("legalnoticecaption", "", "read")) If _TempXMLSetting("legalnoticetext", "", "read") <> "" Then MsgBox(0,"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system - legalnoticetext", _TempXMLSetting("legalnoticetext", "", "read")) Func _TempXMLSetting($temp_setting_update, $temp_setting_value, $option) ; temp variable in .xml / temp value in .xml for that value / read or write Local $main_node_to_temporary = "temporary" If $option = "read" Then If FileExists($settings_temporary) Then $mySettings = _XMLFileOpen ($settings_temporary) ;MsgBox(0,0,_GetFirstValue($main_node_to_temporary & "/" & $temp_setting_update)) Return _GetFirstValue($main_node_to_temporary & "/" & $temp_setting_update) Else Return "" EndIf EndIf If $option = "write" Then If FileExists($settings_temporary) Then MsgBox(0,"file exists",$temp_setting_update & " _ " & $temp_setting_value & " _ " & $option ) $mySettings = _XMLFileOpen ($settings_temporary) If $mySettings = -1 Then MsgBox(0,0, "Error 1") _XMLUpdateField ($main_node_to_temporary & "/" & $temp_setting_update, $temp_setting_value) _XMLTransform ($mySettings) $mySettings.Save ($settings_temporary) Return "" Else _XMLCreateFile ($settings_temporary, "temporary", True) MsgBox(0,"file NOT exists",$temp_setting_update & " _ " & $temp_setting_value & " _ " & $option ) $mySettings = _XMLFileOpen ($settings_temporary) If $mySettings = -1 Then MsgBox(0,0, "Error 2") _XMLCreateRootChild ($temp_setting_update, $temp_setting_value) _XMLTransform ($mySettings) $mySettings.Save ($settings_temporary) Return "" EndIf EndIf EndFunc ;==>_TempXMLSetting Func _GetFirstValue($node) $ret_val = _XMLGetValue ($node) If IsArray($ret_val) Then Return ($ret_val[1]) Else Return SetError(1, 3, 0) EndIf EndFunc ;==>_GetFirstValue Thank You EDIT: Forgot to add 2 first lines. EDIT2: Forgot to add _GetFirstValue function, also note that 'reading' doesnt' seems to work aswell. I have added 2 more lines at the top for reading and it never returns array so _GetFirstValue doesn;t work ;( Edited August 22, 2007 by MadBoy My little company: Evotec (PL version: Evotec) Link to comment Share on other sites More sharing options...
eltorro Posted August 22, 2007 Author Share Posted August 22, 2007 Can anyone help me with this XML problem. I wrote little function that i use to create temp .xml file and it seems that when the first value always gets written properly, the 2nd one doesn't. expandcollapse popup#Include <_XMLDomWrapper.au3> Global $settings_temporary = @ScriptDir & "\post_deployment_temporary.xml" If RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system", "legalnoticetext") <> "" Then _TempXMLSetting("legalnoticetext", RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system", "legalnoticetext"), "write") If RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system", "legalnoticecaption") <> "" Then _TempXMLSetting("legalnoticecaption", RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system", "legalnoticecaption"), "write") If _TempXMLSetting("legalnoticecaption", "", "read") <> "" Then MsgBox(0,"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system - legalnoticecaption", _TempXMLSetting("legalnoticecaption", "", "read")) If _TempXMLSetting("legalnoticetext", "", "read") <> "" Then MsgBox(0,"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system - legalnoticetext", _TempXMLSetting("legalnoticetext", "", "read")) Func _TempXMLSetting($temp_setting_update, $temp_setting_value, $option) ; temp variable in .xml / temp value in .xml for that value / read or write Local $main_node_to_temporary = "temporary" If $option = "read" Then If FileExists($settings_temporary) Then $mySettings = _XMLFileOpen ($settings_temporary) ;MsgBox(0,0,_GetFirstValue($main_node_to_temporary & "/" & $temp_setting_update)) Return _GetFirstValue($main_node_to_temporary & "/" & $temp_setting_update) Else Return "" EndIf EndIf If $option = "write" Then If FileExists($settings_temporary) Then MsgBox(0,"file exists",$temp_setting_update & " _ " & $temp_setting_value & " _ " & $option ) $mySettings = _XMLFileOpen ($settings_temporary) If $mySettings = -1 Then MsgBox(0,0, "Error 1") _XMLUpdateField ($main_node_to_temporary & "/" & $temp_setting_update, $temp_setting_value) _XMLTransform ($mySettings) $mySettings.Save ($settings_temporary) Return "" Else _XMLCreateFile ($settings_temporary, "temporary", True) MsgBox(0,"file NOT exists",$temp_setting_update & " _ " & $temp_setting_value & " _ " & $option ) $mySettings = _XMLFileOpen ($settings_temporary) If $mySettings = -1 Then MsgBox(0,0, "Error 2") _XMLCreateRootChild ($temp_setting_update, $temp_setting_value) _XMLTransform ($mySettings) $mySettings.Save ($settings_temporary) Return "" EndIf EndIf EndFunc ;==>_TempXMLSetting Func _GetFirstValue($node) $ret_val = _XMLGetValue ($node) If IsArray($ret_val) Then Return ($ret_val[1]) Else Return SetError(1, 3, 0) EndIf EndFunc ;==>_GetFirstValue Thank You EDIT: Forgot to add 2 first lines. EDIT2: Forgot to add _GetFirstValue function, also note that 'reading' doesnt' seems to work aswell. I have added 2 more lines at the top for reading and it never returns array so _GetFirstValue doesn;t work ;( The node has to exist before _XMLUpdateField can be used. Check the return or @error from _XMLUpdateField. If there is an error, then use _XMLCreateChildNode. Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code Link to comment Share on other sites More sharing options...
MadBoy Posted August 22, 2007 Share Posted August 22, 2007 The node has to exist before _XMLUpdateField can be used. Check the return or @error from _XMLUpdateField. If there is an error, then use _XMLCreateChildNode.Thank you @eltorro. I have fixed the other problem with reading aswell so all works now! Thanks! My little company: Evotec (PL version: Evotec) Link to comment Share on other sites More sharing options...
zandztrom Posted August 27, 2007 Share Posted August 27, 2007 (edited) Hi,I have been searchin for info about how to delete XML nodes but I can't find any.I'm trying to delete a node(with sub nodes) identfied by an attribute (name=SQLExpress). But I may be a bit thick because I just dont understand how to do this.The xml file from wich I try to delete is containing several nodes with de same name (Package) but different names in the attribute "name". XML files is new for me so I'm well confused about all this with node and atrributes andso on.Attached an example of the xml file below, the part I want to delete is in bold text.<?xml version="1.0" encoding="utf-8"?><Packages xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Package name="SQLExpress" displayName="SQLExpress" version="1.0.0.00" displayVersion="2.0.0.00" category="Applications" description="" <Conditions /> <PreProcess /> <PostProcess /> <Install> <Command groupCondition="" accountid=""/> </Install> <Uninstall /> <Repair /> <Run /> <PatchDependencies /> <Dependencies /> </Package> <Package name="AcroRead" displayName="Acrobat Reader" version="100"> <Conditions/> <PreProcess/> <PostProcess/> <Install> <Command groupCondition=""/> </Install> <Uninstall> </Uninstall> <Repair> <Command groupCondition="" accountid="" filename="MsiExec.exe" arguments="/FOMUS "%PACKAGE_SOURCE% </Package></Packages>I tried: _XMLDeleteAttrNode('/Packages/Package', 'name=SQLExpress') but this must be wrong? Please help Edited August 27, 2007 by zandztrom Link to comment Share on other sites More sharing options...
eltorro Posted August 27, 2007 Author Share Posted August 27, 2007 Try _XMLDeleteNode('/Packages/Package[@ name="SQLExpress"]') . Name is an attribute. ;change paths and filenames respectively #Include "_XMLDomWrapper.au3" _XMLFileOpen("packages.xml") _XMLDeleteNode('/Packages/Package[@ name="SQLExpress"]') ; Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code Link to comment Share on other sites More sharing options...
zandztrom Posted August 27, 2007 Share Posted August 27, 2007 Try _XMLDeleteNode('/Packages/Package[@ name="SQLExpress"]') . Name is an attribute. ;change paths and filenames respectively #Include "_XMLDomWrapper.au3" _XMLFileOpen("packages.xml") _XMLDeleteNode('/Packages/Package[@ name="SQLExpress"]') ; Great, worked like a charm... So easy when you know how; ) Thank you so much for your help! Link to comment Share on other sites More sharing options...
jp10558 Posted August 27, 2007 Share Posted August 27, 2007 Perhaps I'm slow but I really don't see how to do a lot of stuff here. I'm trying to create a quick and dirty GUI for editing sudoers.xml from Sudo For Windows. I've created a gui framework with the autoit gui builder. What I can't see how to do is say, put info from the XML file into anything. I always get -1 returned for any function call I use from the XML wrapper. I have this XML file: <sudoers xmlns="http://sudowin.sourceforge.net/schemas/XmlAuthorizationPlugin/" privilegesGroup="Administrators" invalidLogons="3" timesExceededInvalidLogons="3" invalidLogonTimeout="180" lockoutTimeout="180" logonTimeout="180" startTime="00:00:00.00000" endTime="23:59:59.99999" loggingLevel="Both" allowAllCommands="false"> <users> <userGroup name="Administrators"> <users> <user name="jp10558" allowAllCommands="true"> </user> </users> </userGroup> <userGroup name="Domain Users"> <users> <user name="vis10" allowAllCommands="false"> </user> <user name="user2" allowAllCommands="false"> <commands> <command path="C:\Program Files\UltraVNC\winvnc.exe" /> </commands> </user> </users> <commandGroupRefs> <commandGroupRef commandGroupName="Domain" /> </commandGroupRefs> </userGroup> </users> <commands> <commandGroup name="Domain"> <command path="c:\windows\system32\mmc.exe" argumentString="devmgmt.msc" /> <command path="c:\windows\system32\rundll32.exe" argumentString="/shell32.dll,((SHHelpShortcuts_RunDLL AddPrinter)|(Control_RunDLL powercfg.cpl))/" /> </commandGroup> <commandGroup name="standard"> <!-- Windows XP SP2 files - checksums may vary per operating system, service pack --> <command path="c:\windows\system32\cmd.exe" md5Checksum="eeb024f2c81f0d55936fb825d21a91d6" argumentString="/^/K echo.*$/"/> <command path="c:\windows\explorer.exe" md5Checksum="45757077a47c68a603a79b03a1a836ab" /> <command path="c:\windows\system32\notepad.exe" md5Checksum="388b8fbc36a8558587afc90fb23a3b99" allowedNetworks="192.168.0.226" /> </commandGroup> </commands> </sudoers> How do I pull out the user groups and users from this? What I'd like to do is take this gui: CODEGuiCreate("Edit sudoers.xml", 559, 468,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS)) $Label_1 = GuiCtrlCreateLabel("Group", 10, 10, 40, 20) $Combo_2 = GuiCtrlCreateCombo("", 60, 10, 120, 21) $Label_3 = GuiCtrlCreateLabel("User", 10, 40, 40, 20) $Combo_4 = GuiCtrlCreateCombo("Combo4", 60, 40, 120, 21) $Checkbox_5 = GuiCtrlCreateCheckbox("Allow all commands", 200, 20, 130, 20) $Label_6 = GuiCtrlCreateLabel("Commands allowed", 130, 80, 100, 20) $List_7 = GuiCtrlCreateList("", 130, 100, 420, 344) $Input_8 = GuiCtrlCreateInput("", 10, 160, 110, 20) $Label_9 = GuiCtrlCreateLabel("Add new command", 10, 140, 110, 20) $Input_10 = GuiCtrlCreateInput("", 10, 210, 110, 20) $Label_11 = GuiCtrlCreateLabel("Allowed arguments", 10, 190, 100, 20) $Button_12 = GuiCtrlCreateButton("Add", 40, 250, 60, 20) $Button_13 = GuiCtrlCreateButton("Delete", 280, 70, 60, 20) GuiSetState() And put the usergroups in the combobox and then put in the users that are in that group in the users combo box. I also like to know how I read in info like allowAllCommands="false" for a user so I can then update the checkbox... listbox etc. How do you deal with files that you're not sure how many nodes are in them? The example script knows what data fields to expect, but I don't know how many users there might be, or how many commands might be defined. Link to comment Share on other sites More sharing options...
eltorro Posted August 28, 2007 Author Share Posted August 28, 2007 There was a problem with the order in which certain properties were created on opening an XML file. This was causing MSXML to ignore a namespace setting thus preventing the finding of things within the document. It has been corrected. Please download the "latest greatest". Links are in the first post. Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code Link to comment Share on other sites More sharing options...
eltorro Posted August 28, 2007 Author Share Posted August 28, 2007 (edited) Perhaps I'm slow but I really don't see how to do a lot of stuff here. I'm trying to create a quick and dirty GUI for editing sudoers.xml from Sudo For Windows. I've created a gui framework with the autoit gui builder. What I can't see how to do is say, put info from the XML file into anything. I always get -1 returned for any function call I use from the XML wrapper. I have this XML file: expandcollapse popup<sudoers xmlns="[url="http://sudowin.sourceforge.net/schemas/XmlAuthorizationPlugin/"]http://sudowin.sourceforge.net/schemas/XmlAuthorizationPlugin/[/url]" privilegesGroup="Administrators" invalidLogons="3" timesExceededInvalidLogons="3" invalidLogonTimeout="180" lockoutTimeout="180" logonTimeout="180" startTime="00:00:00.00000" endTime="23:59:59.99999" loggingLevel="Both" allowAllCommands="false"> <users> <userGroup name="Administrators"> <users> <user name="jp10558" allowAllCommands="true"> </user> </users> </userGroup> <userGroup name="Domain Users"> <users> <user name="vis10" allowAllCommands="false"> </user> <user name="user2" allowAllCommands="false"> <commands> <command path="C:\Program Files\UltraVNC\winvnc.exe" /> </commands> </user> </users> <commandGroupRefs> <commandGroupRef commandGroupName="Domain" /> </commandGroupRefs> </userGroup> </users> <commands> <commandGroup name="Domain"> <command path="c:\windows\system32\mmc.exe" argumentString="devmgmt.msc" /> <command path="c:\windows\system32\rundll32.exe" argumentString="/shell32.dll,((SHHelpShortcuts_RunDLL AddPrinter)|(Control_RunDLL powercfg.cpl))/" /> </commandGroup> <commandGroup name="standard"> <command path="c:\windows\system32\cmd.exe" md5Checksum="eeb024f2c81f0d55936fb825d21a91d6" argumentString="/^/K echo.*$/"/> <command path="c:\windows\explorer.exe" md5Checksum="45757077a47c68a603a79b03a1a836ab" /> <command path="c:\windows\system32\notepad.exe" md5Checksum="388b8fbc36a8558587afc90fb23a3b99" allowedNetworks="192.168.0.226" /> </commandGroup> </commands> </sudoers> How do I pull out the user groups and users from this? expandcollapse popup#Include <GuiConstants.au3> #Include <GuiCombo.au3> #Include "_XMLDomWrapper.au3" GuiCreate("Edit sudoers.xml", 559, 468,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS)) $Label_1 = GuiCtrlCreateLabel("Group", 10, 10, 40, 20) $Combo_2 = GuiCtrlCreateCombo("", 60, 10, 120, 21) $Label_3 = GuiCtrlCreateLabel("User", 10, 40, 40, 20) $Combo_4 = GuiCtrlCreateCombo("", 60, 40, 120, 21) $Checkbox_5 = GuiCtrlCreateCheckbox("Allow all commands", 200, 20, 130, 20) $Label_6 = GuiCtrlCreateLabel("Commands allowed", 130, 80, 100, 20) $List_7 = GuiCtrlCreateList("List_7", 130, 100, 420, 344) $Input_8 = GuiCtrlCreateInput("", 10, 160, 110, 20) $Label_9 = GuiCtrlCreateLabel("Add new command", 10, 140, 110, 20) $Input_10 = GuiCtrlCreateInput("", 10, 210, 110, 20) $Label_11 = GuiCtrlCreateLabel("Allowed arguments", 10, 190, 100, 20) $Button_12 = GuiCtrlCreateButton("Add", 40, 250, 60, 20) $Button_13 = GuiCtrlCreateButton("Delete", 280, 70, 60, 20) GuiSetState() main() Exit Func main() _Init() Local $nMsg While 1 $nMsg = GuiGetMsg() Switch $nMsg case $GUI_EVENT_CLOSE ExitLoop case $Combo_2 Local $userNames = _GetUsers(GUICtrlRead($Combo_2)) _GUICtrlComboResetContent ($Combo_4) GuiCtrlSetData($Combo_4,$userNames,StringLeft($userNames,StringInstr($userNames,"|")-1)) _GetAllowAll(GUICtrlRead($Combo_2),GUICtrlRead($Combo_4)) Case $Combo_4 _GetAllowAll(GUICtrlRead($Combo_2),GUICtrlRead($Combo_4)) Case Else EndSwitch WEnd EndFunc Func _Init() If _XMLUDFVersion()<> "1.0.3.79" Then Local $msg = "Your version:"&_XMLUDFVersion() &" is outdated. Please update to version 1.0.3.79"&@LF $msg &="Versions prior to 1.0.3.79 contain a bug that may effect XML data containing namespaces." MsgBox(266288,"_XMLDomWrapper",$msg) Exit EndIf _SetDebug(True) ;It is necessary to specify a key-ref for the name space in order to be able to identify the nodes. $xmlns = "xmlns:sudo='[url="http://sudowin.sourceforge.net/schemas/XmlAuthorizationPlugin/"]http://sudowin.sourceforge.net/schemas/XmlAuthorizationPlugin/[/url]'" _XMLFileOpen("sudoers.xml",$xmlns) If @error Then MsgBox(266304,"Error","File could not be opened") Exit EndIf Local $userGroups = _GetUserGroups() GUICtrlSetData($Combo_2,$userGroups,StringLeft($userGroups,StringInstr($userGroups,"|")-1)) Local $userNames = _GetUsers(GUICtrlRead($Combo_2)) GuiCtrlSetData($Combo_4,$userNames,StringLeft($userNames,StringInstr($userNames,"|")-1)) _GetAllowAll(GUICtrlRead($Combo_2),GUICtrlRead($Combo_4)) EndFunc Func _GetUserGroups() Local $userGroup = _XMLGetChildNodes("//sudo:sudoers/sudo:users") If IsArray($userGroup) Then $groups = "" For $x = 1 to UBound($userGroup)-1 $groupname = _XMLGetAttrib (StringFormat("//sudo:sudoers/sudo:users/sudo:userGroup[%s]",$x),"name" ) if $groupname <> "" Then $groups &= $groupname & "|" EndIf Next ConsoleWrite($groups&@LF) Return $groups EndIf Return "" EndFunc Func _GetUsers($userGroup) if $userGroup = "" Then Return Local $userNodes = _XMLGetChildNodes(StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users',$userGroup)) If IsArray($userNodes) Then $users = "" For $x = 1 to UBound($userNodes)-1 ;StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:user[%d]',$userGroup,$x) Local $username = _XMLGetAttrib (StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:user[%d]',$userGroup,$x),"name" ) if $username <> "" Then $users &= $username &"|" EndIf Next ConsoleWrite($users&@LF) Return $users EndIf Return "" EndFunc Func _GetAllowAll($userGroup,$user) If $userGroup = "" or $user = "" Then Return SetError(1,0,0) EndIf Local $allowall = _XMLGetAttrib (StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:user[@name="%s"]',$userGroup,$user),"allowAllCommands" ) If StringLower($allowall) = "true" Then GuiCtrlSetState($Checkbox_5,$GUI_CHECKED) Return 1 EndIf GuiCtrlSetState($Checkbox_5,$GUI_UNCHECKED) Return 0 EndFunc Func _GetAvailableCommands($userGroup) if $userGroup = "" Then Return Local $userNodes = _XMLGetChildNodes(StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users',$userGroup)) If IsArray($userNodes) Then $users = "" For $x = 1 to UBound($userNodes)-1 Local $username = _XMLGetAttrib (StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:user[%d]',$userGroup,$x),"name" ) if $username <> "" Then $users &= $username &"|" EndIf Next ConsoleWrite($users&@LF) Return $users EndIf Return "" EndFunc Edit: added version check Edited August 31, 2007 by eltorro Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code Link to comment Share on other sites More sharing options...
jp10558 Posted August 28, 2007 Share Posted August 28, 2007 Ok, I'm looking at this, and I'm not really sure what's going on. I tried to edit the _GetAvailableCommands as it didn't seem to do anything and I decided for starters to try and just return what (if any) commandGroupRefs it used. So, I didn't change as many variables as I would have liked as I wasn't sure what they were doing but here it is: Func _GetAvailableCommands($userGroup) if $userGroup = "" Then Return Local $userNodes = _XMLGetChildNodes(StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:commandGroupRefs',$userGroup)); here I thought I could point it to not Users, but the commandGroupRefs that is just subordinate to the first Users. If IsArray($userNodes) Then $users = "" For $x = 1 to UBound($userNodes)-1 Local $username = _XMLGetAttrib (StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:commandGroupRefs[%d]',$userGroup,$x),"commandGroupName" ); here I thought I would point to instead of the name field, the field name I wanted. if $username <> "" Then $users &= $username &"|" EndIf Next ConsoleWrite($users&@LF) Return $users; Here may be where I'm screwed up... What is this returning? A variable or an array? EndIf Return "" EndFunc Then I tried to add a case to fill/create a lable with the commandGroupRefs name (I think there may only be one, but here let's assume there is only one per usergroup): Case $Label_13 $command = _GetAvailableCommands(GUICtrlRead($Combo_2)) $Label_13 = GuiCtrlCreateLabel($command, 440, 15, 100, 20) This has no discrnable effect - perhaps because $command is an array, or something - doesn't look like an array though. Maybe this isn't possible, but it would be really nice if there was something like the ini functions built into autoit - that is I say _read(/settings/user,username) and have _write(/settings/user,field,data). Perhaps it's just because I don't understand this well enough. Link to comment Share on other sites More sharing options...
MadBoy Posted August 28, 2007 Share Posted August 28, 2007 @eltorro:Can you please check this http://www.autoitscript.com/forum/index.ph...&pid=392688I'm wondering if there is better way to code this function? You got any ideas? My little company: Evotec (PL version: Evotec) Link to comment Share on other sites More sharing options...
eltorro Posted August 28, 2007 Author Share Posted August 28, 2007 Ok, I'm looking at this, and I'm not really sure what's going on. I tried to edit the _GetAvailableCommands as it didn't seem to do anything and I decided for starters to try and just return what (if any) commandGroupRefs it used. So, I didn't change as many variables as I would have liked as I wasn't sure what they were doing but here it is: Func _GetAvailableCommands($userGroup) if $userGroup = "" Then Return Local $userNodes = _XMLGetChildNodes(StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:commandGroupRefs',$userGroup)); here I thought I could point it to not Users, but the commandGroupRefs that is just subordinate to the first Users. If IsArray($userNodes) Then $users = "" For $x = 1 to UBound($userNodes)-1 Local $username = _XMLGetAttrib (StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:commandGroupRefs[%d]',$userGroup,$x),"commandGroupName" ); here I thought I would point to instead of the name field, the field name I wanted. if $username <> "" Then $users &= $username &"|" EndIf Next ConsoleWrite($users&@LF) Return $users; Here may be where I'm screwed up... What is this returning? A variable or an array? EndIf Return "" EndFunc Then I tried to add a case to fill/create a lable with the commandGroupRefs name (I think there may only be one, but here let's assume there is only one per usergroup): Case $Label_13 $command = _GetAvailableCommands(GUICtrlRead($Combo_2)) $Label_13 = GuiCtrlCreateLabel($command, 440, 15, 100, 20) This has no discrnable effect - perhaps because $command is an array, or something - doesn't look like an array though. Maybe this isn't possible, but it would be really nice if there was something like the ini functions built into autoit - that is I say _read(/settings/user,username) and have _write(/settings/user,field,data). Perhaps it's just because I don't understand this well enough.That was my fault, I forgot to pull the code for that out. This will read the command group from the usergroup then load the paths from the commands to the list box. expandcollapse popup#Include <GuiConstants.au3> #Include <GuiCombo.au3> #Include <GuiList.au3> #Include "Z:\fileman\_XMLDomWrapper.au3" GuiCreate("Edit sudoers.xml", 559, 468,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS)) $Label_1 = GuiCtrlCreateLabel("Group", 10, 10, 40, 20) $Combo_2 = GuiCtrlCreateCombo("", 60, 10, 120, 21) $Label_3 = GuiCtrlCreateLabel("User", 10, 40, 40, 20) $Combo_4 = GuiCtrlCreateCombo("", 60, 40, 120, 21) $Checkbox_5 = GuiCtrlCreateCheckbox("Allow all commands", 200, 20, 130, 20) $Label_6 = GuiCtrlCreateLabel("Commands allowed", 130, 80, 100, 20) $List_7 = GuiCtrlCreateList("", 130, 100, 420, 344) $Input_8 = GuiCtrlCreateInput("", 10, 160, 110, 20) $Label_9 = GuiCtrlCreateLabel("Add new command", 10, 140, 110, 20) $Input_10 = GuiCtrlCreateInput("", 10, 210, 110, 20) $Label_11 = GuiCtrlCreateLabel("Allowed arguments", 10, 190, 100, 20) $Button_12 = GuiCtrlCreateButton("Add", 40, 250, 60, 20) $Button_13 = GuiCtrlCreateButton("Delete", 280, 70, 60, 20) GuiSetState() main() Exit Func main() _Init() Local $nMsg While 1 $nMsg = GuiGetMsg() Switch $nMsg case $GUI_EVENT_CLOSE ExitLoop case $Combo_2 Local $userNames = _GetUsers(GUICtrlRead($Combo_2)) _GUICtrlComboResetContent ($Combo_4) GuiCtrlSetData($Combo_4,$userNames,StringLeft($userNames,StringInstr($userNames,"|")-1)) _UpdateUi(GUICtrlRead($Combo_2),GUICtrlRead($Combo_4)) Case $Combo_4 _UpdateUi(GUICtrlRead($Combo_2),GUICtrlRead($Combo_4)) Case Else EndSwitch WEnd EndFunc Func _Init() If _XMLUDFVersion()<> "1.0.3.79" Then Local $msg = "Your version:"&_XMLUDFVersion() &" is outdated. Please update to version 1.0.3.79"&@LF $msg &="Versions prior to 1.0.3.79 contain a bug that may effect XML data containing namespaces." MsgBox(266288,"_XMLDomWrapper",$msg) Exit EndIf _SetDebug(True) ;It is necessary to specify a key-ref for the name space in order to be able to identify the nodes. $xmlns = "xmlns:sudo='http://sudowin.sourceforge.net/schemas/XmlAuthorizationPlugin/'" _XMLFileOpen("sudoers.xml",$xmlns) If @error Then MsgBox(266304,"Error","File could not be opened") Exit EndIf Local $userGroups = _GetUserGroups() GUICtrlSetData($Combo_2,$userGroups,StringLeft($userGroups,StringInstr($userGroups,"|")-1)) Local $userNames = _GetUsers(GUICtrlRead($Combo_2)) GuiCtrlSetData($Combo_4,$userNames,StringLeft($userNames,StringInstr($userNames,"|")-1)) _GetAllowAll(GUICtrlRead($Combo_2),GUICtrlRead($Combo_4)) EndFunc Func _UpdateUi($group,$user) _GetAllowAll($group,$user) Local $commandList = _GetAvailableCommands($group) _GUICtrlListClear ($List_7) GuiCtrlSetData($List_7,$commandList) EndFunc Func _GetUserGroups() Local $userGroup = _XMLGetChildNodes("//sudo:sudoers/sudo:users") If IsArray($userGroup) Then $groups = "" For $x = 1 to UBound($userGroup)-1 $groupname = _XMLGetAttrib (StringFormat("//sudo:sudoers/sudo:users/sudo:userGroup[%s]",$x),"name" ) if $groupname <> "" Then $groups &= $groupname & "|" EndIf Next ConsoleWrite($groups&@LF) Return $groups EndIf Return "" EndFunc Func _GetUsers($userGroup) if $userGroup = "" Then Return Local $userNodes = _XMLGetChildNodes(StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users',$userGroup)) If IsArray($userNodes) Then $users = "" For $x = 1 to UBound($userNodes)-1 ;StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:user[%d]',$userGroup,$x) Local $username = _XMLGetAttrib (StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:user[%d]',$userGroup,$x),"name" ) if $username <> "" Then $users &= $username &"|" EndIf Next ConsoleWrite($users&@LF) Return $users EndIf Return "" EndFunc Func _GetAllowAll($userGroup,$user) If $userGroup = "" or $user = "" Then Return SetError(1,0,0) EndIf Local $allowall = _XMLGetAttrib (StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:user[@name="%s"]',$userGroup,$user),"allowAllCommands" ) If StringLower($allowall) = "true" Then GuiCtrlSetState($Checkbox_5,$GUI_CHECKED) Return 1 EndIf GuiCtrlSetState($Checkbox_5,$GUI_UNCHECKED) Return 0 EndFunc Func _GetAvailableCommands($userGroup) if $userGroup = "" Then Return Local $commandGroup = _XMLGetAttrib (StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:commandGroupRefs/sudo:commandGroupRef',$userGroup),"commandGroupName" ) if @error = 0 And $commandGroup <> "" Then ConsoleWrite("CommandGroup="&$commandGroup&@LF) Local $commandCount = _XMLGetChildNodes(StringFormat('//sudo:sudoers/sudo:commands/sudo:commandGroup[@name="%s"]',$commandGroup)) if IsArray($commandCount) Then Local $commands = "" Local $c = 0 For $x = 0 to UBound($commandCount)-1 if $commandCount[$x] = "command" Then $c+=1 Local $command = _XMLGetAttrib(StringFormat('//sudo:sudoers/sudo:commands/sudo:commandGroup[@name="%s"]/sudo:command[%d]',$commandGroup,$c),"path") if $command <> "" Then $commands &= $command &"|" EndIf EndIf Next Return $commands EndIf EndIf Return "" EndFunc Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code Link to comment Share on other sites More sharing options...
Seeker Posted August 30, 2007 Share Posted August 30, 2007 How to improve speed?I have a working code to produce very complex XML. But. The speed is terrific. I mean process is really slow. I have debuggedmy code with timecodes and what I have discovered is that:_XMLCreateChildNode ("/Schedule/Group/Items", "Clip")At this point code is fast enough. But in for-loop..._XMLCreateChildNode ("/Schedule/Group/Items/Clip["&$iClip&"]/SubStreams/SubStream["&$iSubstream&"]", "Event")Everything is slowing down. On every run there is at least 25 lines of "_XMLCreateChildNode" funcrtions adding nodes and setting values forthose nodes.With 5 clips having 3 substreams containing 4 event on each takes about 20 seconds. Am I doing something wrong or is the parser really that slow?Is there any way to speed up this script?And ElTorro - thank you for this really fantastic UDF. And BTW thank you finding that 'magick fix' for namespaces. You helped me a lot with that! Link to comment Share on other sites More sharing options...
jp10558 Posted August 30, 2007 Share Posted August 30, 2007 How do you write to a specific xml node when, like in my case, the difference is in an attribute like <userGroup name="Administrators">? I tried _XMLCreateChildWAttr ( '/sudoers/users/userGroup name="'& GuiCtrlRead($Combo_2) & '"/users', "user", "name", GUICtrlRead($Combo_4), "","" ) but that gave a COM error - also, I need to create the node with both the name and allowAllCommands="true" or allowAllCommands="false" depending on the checkbox (but I just want to write one or the other here... Link to comment Share on other sites More sharing options...
eltorro Posted August 30, 2007 Author Share Posted August 30, 2007 How to improve speed? I have a working code to produce very complex XML. But. The speed is terrific. I mean process is really slow. I have debugged my code with timecodes and what I have discovered is that: _XMLCreateChildNode ("/Schedule/Group/Items", "Clip") At this point code is fast enough. But in for-loop... _XMLCreateChildNode ("/Schedule/Group/Items/Clip["&$iClip&"]/SubStreams/SubStream["&$iSubstream&"]", "Event") Everything is slowing down. On every run there is at least 25 lines of "_XMLCreateChildNode" funcrtions adding nodes and setting values for those nodes. With 5 clips having 3 substreams containing 4 event on each takes about 20 seconds. Am I doing something wrong or is the parser really that slow? Is there any way to speed up this script? And ElTorro - thank you for this really fantastic UDF. And BTW thank you finding that 'magick fix' for namespaces. You helped me a lot with that! Well, it's not a speed demon but if your using the latest version, try _XMLSetAutoSave(False) before beginning a long series. If you do that, be sure to call _XMLSaveDoc() because your changes/additions won't be committed unless you do. You can restore built in saving with _XMLSetAutoSave(). Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code Link to comment Share on other sites More sharing options...
eltorro Posted August 30, 2007 Author Share Posted August 30, 2007 How do you write to a specific xml node when, like in my case, the difference is in an attribute like <userGroup name="Administrators">? I tried _XMLCreateChildWAttr ( '/sudoers/users/userGroup name="'& GuiCtrlRead($Combo_2) & '"/users', "user", "name", GUICtrlRead($Combo_4), "","" ) but that gave a COM error - also, I need to create the node with both the name and allowAllCommands="true" or allowAllCommands="false" depending on the checkbox (but I just want to write one or the other here... $Group = "Administrators" $User = "Josef" $AllowAll = "true" $ns = '[url="http://sudowin.sourceforge.net/schemas/XmlAuthorizationPlugin/"]http://sudowin.sourceforge.net/schemas/XmlAuthorizationPlugin/[/url]' ;define this globally at start of script. ;;; create a new user Local $aAttrs[2]=["name","allowAllCommands"] Local $aVals[2] =[$User,$AllowAll] _XMLCreateChildWAttr(StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users',$Group),"user",$aAttrs,$aVals,"",$ns) ;;; Change a user _XMLSetAttrib(StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:users/sudo:user[@name="%s"]' ,$Group,$User),"allowAllCommands",$AllowAll ) Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code Link to comment Share on other sites More sharing options...
nikink Posted August 31, 2007 Share Posted August 31, 2007 Can this perform conversions from csv to xml, by chance? Link to comment Share on other sites More sharing options...
eltorro Posted August 31, 2007 Author Share Posted August 31, 2007 Can this perform conversions from csv to xml, by chance?There is no built in function to do it. With a good csv parser it would not be hard to write a UDF to do it. Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code Link to comment Share on other sites More sharing options...
jp10558 Posted September 7, 2007 Share Posted September 7, 2007 Say I want to delete something from the file - is there some guide to how to write the XPath? Specifically I think I'd want to delete the user by the Name attribute... Also, I have adding a user worked out, but it's creating <user name="test" allowAllCommands="true"/> Instead of the reference <user name="test" allowAllCommands="true"> </user> I'm not sure it this will cause parsing issues for sudowin or not. Link to comment Share on other sites More sharing options...
eltorro Posted September 7, 2007 Author Share Posted September 7, 2007 Say I want to delete something from the file - is there some guide to how to write the XPath? Specifically I think I'd want to delete the user by the Name attribute... To delete a node, use something like _XMLDeleteNode(StringFormat('//sudo:sudoers/sudo:users/sudo:userGroup[@name="%s"]/sudo:user[@name="%s"]',$userGroup,$userName)) Also, I have adding a user worked out, but it's creating <user name="test" allowAllCommands="true"/> Instead of the reference <user name="test" allowAllCommands="true"> </user> I'm not sure it this will cause parsing issues for sudowin or not. There is not any functionally difference between them. Regards, [indent]ElTorro[/indent][font="Book"] Decide, Commit, Achieve[/font]_ConfigIO.au3Language Translation --uses Google(tm) MsgBox Move XML wrapper UDF XML2TreeView Zip functionality Split your GUI Save Print ScreenZipPluginEdit In Place listviewSome of my scripts on Google code 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