nssatomic Posted September 25, 2009 Share Posted September 25, 2009 I'm having a problem writing to an xml file up to a certain point. My script will find the line <ID>7394</ID> and <STATUS>4</STATUS> and then insert the line <REVIEWER_DETAILS>File IO Permission</REVIEWER_DETAILS>. However I want it to stop once it finds the line <ID_NUMBER>815</ID_NUMBER>. It is very important that it always inserts at the same point after <STATUS>4</STATUS>. Here is a sample xml file. <ID_NUMBER>603</ID_NUMBER> <ORIGINAL_ID>603</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> - <VULN_STATE> - <VULN> <ID>7394</ID> <STATUS>4</STATUS> <SEVERITY_OVERRIDE>0</SEVERITY_OVERRIDE> <STATUS_OVERRIDE>0</STATUS_OVERRIDE> </VULN> - <VULN> <ID>7395</ID> <STATUS>4</STATUS> <SEVERITY_OVERRIDE>0</SEVERITY_OVERRIDE> <STATUS_OVERRIDE>0</STATUS_OVERRIDE> </VULN> - <VULN> <ID_NUMBER>815</ID_NUMBER> <ORIGINAL_ID>815</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> - <VULN_STATE> - <VULN> <ID>7394</ID> <STATUS>4</STATUS> <SEVERITY_OVERRIDE>0</SEVERITY_OVERRIDE> <STATUS_OVERRIDE>0</STATUS_OVERRIDE> </VULN> And my sample code. #Include <File.au3> #Include <Array.au3> Dim $content $source = "C:\test.xml" _FileReadToArray($source, $content) _7394() ;File IO Permission Func _7394() ;File IO Permission Do for $iLine = 1 to $content[0] step 1 if StringInStr($content[$iLine], "<ID>7394</ID>") Then $nextline1 = ($iLine + 1) if StringInStr($content[$nextline1], "<STATUS>4</STATUS>") Then $nextline2 = ($nextline1 + 1) _FileWriteToLine($source, $nextline2, "<REVIEWER_DETAILS>File IO Permission</REVIEWER_DETAILS>", 0) EndIf EndIf Next Until $content = "<ID_NUMBER>815</ID_NUMBER>" EndFunc Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 25, 2009 Share Posted September 25, 2009 I'm having a problem writing to an xml file up to a certain point. My script will find the line <ID>7394</ID> and <STATUS>4</STATUS> and then insert the line <REVIEWER_DETAILS>File IO Permission</REVIEWER_DETAILS>. However I want it to stop once it finds the line <ID_NUMBER>815</ID_NUMBER>. It is very important that it always inserts at the same point after <STATUS>4</STATUS>. Here is a sample xml file. <ID_NUMBER>603</ID_NUMBER> <ORIGINAL_ID>603</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> - <VULN_STATE> - <VULN> <ID>7394</ID> <STATUS>4</STATUS> <SEVERITY_OVERRIDE>0</SEVERITY_OVERRIDE> <STATUS_OVERRIDE>0</STATUS_OVERRIDE> </VULN> - <VULN> <ID>7395</ID> <STATUS>4</STATUS> <SEVERITY_OVERRIDE>0</SEVERITY_OVERRIDE> <STATUS_OVERRIDE>0</STATUS_OVERRIDE> </VULN> - <VULN> <ID_NUMBER>815</ID_NUMBER> <ORIGINAL_ID>815</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> - <VULN_STATE> - <VULN> <ID>7394</ID> <STATUS>4</STATUS> <SEVERITY_OVERRIDE>0</SEVERITY_OVERRIDE> <STATUS_OVERRIDE>0</STATUS_OVERRIDE> </VULN> And my sample code. #Include <File.au3> #Include <Array.au3> Dim $content $source = "C:\test.xml" _FileReadToArray($source, $content) _7394() ;File IO Permission Func _7394() ;File IO Permission Do for $iLine = 1 to $content[0] step 1 if StringInStr($content[$iLine], "<ID>7394</ID>") Then $nextline1 = ($iLine + 1) if StringInStr($content[$nextline1], "<STATUS>4</STATUS>") Then $nextline2 = ($nextline1 + 1) _FileWriteToLine($source, $nextline2, "<REVIEWER_DETAILS>File IO Permission</REVIEWER_DETAILS>", 0) EndIf EndIf Next Until $content = "<ID_NUMBER>815</ID_NUMBER>" EndFunc Have you looked at eltorro's _XMLDOMWrapper.au3 UDF? It allows you to address XML elements directly with XPath, without all the text parsing of your own. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 25, 2009 Share Posted September 25, 2009 (edited) Well, first you need some valid XML. Is this more like what your example was supposed to be? <?xml version="1.0"?> <ROOT> <ID_NUMBER>603</ID_NUMBER> <ORIGINAL_ID>603</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> <VULN_STATE> <VULN> <ID>7394</ID> <STATUS>4</STATUS> <SEVERITY_OVERRIDE>0</SEVERITY_OVERRIDE> <STATUS_OVERRIDE>0</STATUS_OVERRIDE> </VULN> <VULN> <ID>7395</ID> <STATUS>4</STATUS> <SEVERITY_OVERRIDE>0</SEVERITY_OVERRIDE> <STATUS_OVERRIDE>0</STATUS_OVERRIDE> </VULN> <VULN> <ID_NUMBER>815</ID_NUMBER> <ORIGINAL_ID>815</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> </VULN> <VULN> <ID>7394</ID> <STATUS>4</STATUS> <SEVERITY_OVERRIDE>0</SEVERITY_OVERRIDE> <STATUS_OVERRIDE>0</STATUS_OVERRIDE> </VULN> </VULN_STATE> </ROOT> Edit: Would have helped if my version was well formed (no root node). Fixed it. Edited September 25, 2009 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
nssatomic Posted September 25, 2009 Author Share Posted September 25, 2009 Well, first you need some valid XML. Is this more like what your example was supposed to be?Yes it is. I'm reviewing the XMLDomWrapper functions now. I'm pretty clueless when it comes to xml but maybe I can figure it out. Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 25, 2009 Share Posted September 25, 2009 Yes it is. I'm reviewing the XMLDomWrapper functions now. I'm pretty clueless when it comes to xml but maybe I can figure it out. Here's an example using XPath: #include <_XMLDOMWrapper.au3> #include <Array.au3> Global $sXML = @ScriptDir & "\Test1.xml" If _XMLFileOpen($sXML) = -1 Or @error Then MsgBox(16, "Error", "Error opening file.") Exit EndIf $iVulnCnt = _XMLGetNodeCount("/ROOT/VULN_STATE/VULN") ConsoleWrite("$iVulnCnt = " & $iVulnCnt & @LF) For $iVuln = 1 To $iVulnCnt $avNodes = _XMLSelectNodes("/ROOT/VULN_STATE/VULN[" & $iVuln & "]/*") If IsArray($avNodes) Then For $iNode = 1 To $avNodes[0] $avValue = _XMLGetValue("/ROOT/VULN_STATE/VULN[" & $iVuln & "]/" & $avNodes[$iNode]) If IsArray($avValue) Then $avNodes[$iNode] &= " = " & $avValue[1] Else ConsoleWrite($iVuln & ": " & $iNode & ": Not and array" & @LF) EndIf Next _ArrayDisplay($avNodes, $iVuln & ": $avNodes") Else ConsoleWrite($iVuln & ": Not an array" & @LF) EndIf Next All this does is get the number of VULN nodes, then display all the child nodes under each one, with its value. Tested with the (fixed) XML I posted above. Hope that helps. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
nssatomic Posted September 28, 2009 Author Share Posted September 28, 2009 (edited) Thanks for the example. I'm slowly learning how to work with this by creating my own xml file with autoit. I do have another question. What if the xml document you are trying to edit has several identical paths in it? For example lets say you have path SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE and this occurs several times throughout the document. You need to create different sets of data in different TARGET_STATE entries so how would you do that? Here's an example script I wrote showing what happens. #include <_XMLDOMWrapper.au3> _XMLCreateFile("C:\testxml.xml", "SESSION_FILE", False) _XMLFileOpen("C:\testxml.xml") _XMLCreateRootChild("ASSET_INFORMATION") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION","TARGET_INFORMATION") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION","TARGET_STATE") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","ID_NUMBER", "603") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","ORIGINAL_ID", "603") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","PHYSICAL_PARENT", "0") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","SELECTED_POLICY", "1") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","VULN_STATE", "") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION","TARGET_STATE") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","ID_NUMBER", "604") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","ORIGINAL_ID", "604") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","PHYSICAL_PARENT", "0") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","SELECTED_POLICY", "1") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","VULN_STATE", "") Edited September 28, 2009 by nssatomic Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 28, 2009 Share Posted September 28, 2009 Thanks for the example. I'm slowly learning how to work with this by creating my own xml file with autoit. I do have another question. What if the xml document you are trying to edit has several identical paths in it? For example lets say you have path SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE and this occurs several times throughout the document. You need to create different sets of data in different TARGET_STATE entries so how would you do that? Here's an example script I wrote showing what happens. #include <_XMLDOMWrapper.au3> _XMLCreateFile("C:\testxml.xml", "SESSION_FILE", False) _XMLFileOpen("C:\testxml.xml") _XMLCreateRootChild("ASSET_INFORMATION") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION","TARGET_INFORMATION") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION","TARGET_STATE") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","ID_NUMBER", "603") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","ORIGINAL_ID", "603") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","PHYSICAL_PARENT", "0") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","SELECTED_POLICY", "1") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","VULN_STATE", "") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION","TARGET_STATE") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","ID_NUMBER", "604") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","ORIGINAL_ID", "604") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","PHYSICAL_PARENT", "0") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","SELECTED_POLICY", "1") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE","VULN_STATE", "") Remember those are XPath paths (see the link in Post #5 for a tutorial). Where you have multiple nodes at the same level with the same ID, they have a 1-based index (looks like AutoIt's array index, except those are 0-based). So the third one is ".../TARGET_STATE[3]". What the easiest method is depends on where the data is coming from. This example pulls it from a 2D array: #include <_XMLDOMWrapper.au3> Global $sXmlFile = @ScriptDir & "\testxml.xml" ; Create array of "TARGET_STATE" data to add Global $avArray[4][5] For $n = 0 To UBound($avArray) - 1 $avArray[$n][0] = String(603 + $n) ; ID_NUMBER $avArray[$n][1] = String(603 + $n) ; ORIGINAL_ID $avArray[$n][2] = "0" ; PHYSICAL_PARENT $avArray[$n][3] = "1" ; SELECTED_POLICY $avArray[$n][4] = "" ; VULN_STATE Next ; Create XML file and basic path _XMLCreateFile($sXmlFile, "SESSION_FILE", False) _XMLFileOpen($sXmlFile) _XMLCreateRootChild("ASSET_INFORMATION") _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION", "TARGET_INFORMATION") For $n = 0 To UBound($avArray) - 1 ; Add required "TARGET_STATE" node _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION", "TARGET_STATE") ; Add child nodes _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE[" & $n + 1 & "]", "ID_NUMBER", $avArray[$n][0]) _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE[" & $n + 1 & "]", "ORIGINAL_ID", $avArray[$n][1]) _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE[" & $n + 1 & "]", "PHYSICAL_PARENT", $avArray[$n][2]) _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE[" & $n + 1 & "]", "SELECTED_POLICY", $avArray[$n][3]) _XMLCreateChildNode("SESSION_FILE/ASSET_INFORMATION/TARGET_INFORMATION/TARGET_STATE[" & $n + 1 & "]", "VULN_STATE", $avArray[$n][4]) Next The resulting TestXml.xml file looks like this (but not indented): <?xml version="1.0"?> <SESSION_FILE> <ASSET_INFORMATION> <TARGET_INFORMATION> <TARGET_STATE> <ID_NUMBER>603</ID_NUMBER> <ORIGINAL_ID>603</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> <VULN_STATE/> </TARGET_STATE> <TARGET_STATE> <ID_NUMBER>604</ID_NUMBER> <ORIGINAL_ID>604</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> <VULN_STATE/> </TARGET_STATE> <TARGET_STATE> <ID_NUMBER>605</ID_NUMBER> <ORIGINAL_ID>605</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> <VULN_STATE/> </TARGET_STATE> <TARGET_STATE> <ID_NUMBER>606</ID_NUMBER> <ORIGINAL_ID>606</ORIGINAL_ID> <PHYSICAL_PARENT>0</PHYSICAL_PARENT> <SELECTED_POLICY>1</SELECTED_POLICY> <VULN_STATE/> </TARGET_STATE> </TARGET_INFORMATION> </ASSET_INFORMATION> </SESSION_FILE> Hope that helps! Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
mrmacadamia Posted October 1, 2009 Share Posted October 1, 2009 (edited) Yes! This is a great Example !! Now i can learn how to use the udf. Thanks! Edited October 1, 2009 by mrmacadamia 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