Jump to content

issue writing to xml file


nssatomic
 Share

Recommended Posts

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

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.

:D

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

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>

:D

Edit: Would have helped if my version was well formed (no root node). Fixed it.

Edited 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

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.

:D

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

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 by nssatomic
Link to comment
Share on other sites

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!

:D

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...