Jump to content

XML DOM wrapper (COM)


eltorro
 Share

Recommended Posts

I am trying to capture the value of <is_hidden>false</is_hidden> as a variable from the node? control type ="ADVTEXTBOX_CTRL" where the element ID is user_id. I am suspecting I missing a whole lot in relation to nodes and such.

Sorry, I don't use the UDF. If you want to try to use the COM-object directly, here is an example:

; create object
$oXML = ObjCreate("MsXml.DOMDocument")
 
; load file
$oXML.load('C:\Users\ProgAndy\AppData\Local\Temp\file.xml')
; use XPath
$oXML.setProperty("SelectionLanguage", "XPath")
 
; read value
$fIsHidden = False ; Default value if does not exist
$oIsHidden = $oXML.selectSingleNode('content/control[@name="txtPassword"]/is_hidden')
If IsObj($oIsHidden) Then $fIsHidden = $oIsHidden.text = "true"
$oIsHidden = 0
 
MsgBox(0, 'is_hidden', $fIsHidden)
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Sorry, I don't use the UDF. If you want to try to use the COM-object directly, here is an example:

; create object
$oXML = ObjCreate("MsXml.DOMDocument")
 
; load file
$oXML.load('C:\Users\ProgAndy\AppData\Local\Temp\file.xml')
; use XPath
$oXML.setProperty("SelectionLanguage", "XPath")
 
; read value
$fIsHidden = False ; Default value if does not exist
$oIsHidden = $oXML.selectSingleNode('content/control[@name="txtPassword"]/is_hidden')
If IsObj($oIsHidden) Then $fIsHidden = $oIsHidden.text = "true"
$oIsHidden = 0
 
MsgBox(0, 'is_hidden', $fIsHidden)

Am I missing something? I tried this and the value always comes back as False, no matter the value in the file. I also modified the code to read another section and it comes back as blank.

<control type="LABEL_CTRL" name="control_2262">

<element_name>LABEL_7</element_name>

<y>44</y>

<x>1</x>

<h>16</h>

<w>221</w>

<text>SS8.1.2.2.0.0.0.008_MA2.0.0</text>

<font_name>Arial</font_name>

<font_size>9.75</font_size>

</control>

I modified to read this section from the text line.

What am I missing?

Link to comment
Share on other sites

Sorry, I used the wrong object and the XPath must begin with //. The correct object is MsXML2.DOMdocument. After these changes. the code is correct, but you XML is still invalid. a control and a content-tag are not closed.

; create object
$oXML = ObjCreate("Msxml2.DOMDocument")

; load file
$oXML.load('C:\Users\ProgAndy\AppData\Local\Temp\file.xml')
; use XPath
$oXML.setProperty("SelectionLanguage", "XPath")

; read value
$fIsHidden = False ; Default value if does not exist
$oIsHidden = $oXML.selectSingleNode('//content/control[@name="txtPassword"]/is_hidden')
If IsObj($oIsHidden) Then $fIsHidden = ($oIsHidden.text = "true")
$oIsHidden = 0

MsgBox(0, 'is_hidden', $fIsHidden)

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

You should learn XPath, it is really useful :mellow: Even the XML DOM wrapper uses it.

http://www.w3schools.com/xpath/default.asp

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

  • 1 month later...

#include <_XMLDomWrapper.au3>
#Include <Array.au3>

; OPEN XML FILE
$xmlns = "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:cpe='http://cpe.mitre.org/language/2.0' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:xhtml='http://www.w3.org/1999/xhtml' xmlns:dsig='http://www.w3.org/2000/09/xmldsig#' xmlns='http://checklists.nist.gov/xccdf/1.1'"
$oXMLFile = _XMLFileOpen("Stig.xml", $xmlns)
Switch @error
    Case 0
        ConsoleWrite("No Error" & @CRLF &": "&@Extended)
    Case 1
        ConsoleWrite("Parse Error" & @CRLF &": "&@Extended)
    Case 2
        ConsoleWrite("No Object" & @CRLF &": "&@Extended)
EndSwitch

$entry_count =  _XMLGetNodeCount('//Group')

ConsoleWrite("Entry Count: " & $entry_count & @CRLF)

I have been beating my head against a wall from a few days now and can not seem to figure this out. I need to parse through an XML document and pull some information. I have been trying to get it to return a node count of all the group nodes but cant seem to even get that to work. My end goal is to be able to return all the <group id=> along with <rule severity> as well as the <title> under <rule>. I am a complete noob when it comes to XML. I have left a small subset of what the true XML file looks like. the real file is over 1MB in size. Any Help is appriciated. thanks

STIG1.xml

Link to comment
Share on other sites

Hi,

your XML file is invalid because it contains invalid chars:

Line 61, pos. 41, offset 0x93 and 0x94.

These chars should not be present in a file using the Unicode UTF-8 encoding.

Greets,

-supersonic.

I took out the invalid chars and it still performs in the same manor
Link to comment
Share on other sites

Your XML file is still invalid:

File C:\Users\supersonic\Desktop\STIG1.xml is not valid.

Element <ProfileDescription> is not allowed under element <description>.

Reason: The following elements are expected at this location (see below)

<cdf:sub>

{http://www.w3.org/1999/xhtml}

Annotations of type 'cdf:htmlTextWithSubType' (see below)

Type for a string with embedded Value substitutions and

XHTML elements, and an xml:lang attribute. Elements of

this type can also have an override attribute to help

manage inheritance. [Note: this definition is rather

loose, it allows anything whatsoever to occur insides

XHTML tags inside here. Further, constraints of the XHTML

schema do not get checked! It might be possible to solve

this using XML Schema redefinition features.]

Error location: Benchmark / Profile / description / ProfileDescription

Details

cvc-model-group: Element <ProfileDescription> unexpected by type 'cdf:htmlTextWithSubType' of element <description>.

cvc-elt.5.2.1: The element <description> is not valid with respect to the actual type definition 'cdf:htmlTextWithSubType'.

Link to comment
Share on other sites

i get an error when trying _XMLNodeExists ("/data/client/123_asdf/group") why?

error msg like : Предпологается NodeTest, /data/cleint/--->123<---_asd/group, неопознанная ошибка, err.number 80020009, scriptline 1733

something like that

btw when i try check node with name "asdf_123" got no error, why if i put number first == error? :graduated:

- I want program that crack all other programs...- Let's split up, i'll search this program and you'll find crack for it. ^_^'

Link to comment
Share on other sites

Thanks for the XML UDF. It's working great.

FYI -- The function _MSXML_NodeExists() is defined two times in <_MSXML.au3>, on line 1024 and 1640. I just commented out the definition on line 1024 since the other one looks to be more robust.

Link to comment
Share on other sites

  • 3 months later...

Eltorro thank you for the UDF.

I have two questions about XML functions though:

1) I've noticed that _XMLCreate functions doesn't check for the nodes with same properties and creates a new ones even if that node already exists. I know it is something that ini format lacks and in some cases is much needed but in couple of cases I needed to update existing nodes and only create new ones if the same one does't exist already.

I wrote some very basic functions that work like iniwrite. Ex:

Func _XMLWriteChildNode($strXPath2, $strNode2, $strData2 = "", $strNameSpc2 = "")
    If not IsObj($objDoc) then
        _XMLError("No object passed to function _XMLCreateChildNode")
        Return SetError(1,20,-1)
    EndIf

    Local $i_tip_return, $i_tip_XPath =$strXPath2 & "/" &  $strNode2

    If  _XMLNodeExists($i_tip_XPath) = 1 Then
        $i_tip_return = _XMLUpdateField ( $i_tip_XPath , $strData2)
    Else
        $i_tip_return = _XMLCreateChildNode($strXPath2, $strNode2, $strData2, $strNameSpc2)
    EndIf

    Return $i_tip_return
EndFunc

But than it occured to me that this is a well written udf and there may be some valid reason(s) not to use iniwrite kind of aproach with xml. Can anybody comment on this :)

2) I found that XML takes considerably longer write times. I wonder if there is a way to make it faster like flushing flie after a certainamount of operations etc. To write 85 nodes, XML writing functions noticeably blocks the script for couple of seconds.

Thanks everyone in advance and thank you eltorro again for the udf.

Regards

Tip

Edited by tip

[center]MsgBox_Tipped: Eye candy msgboxes/inputboxes/loginboxes. | CreateBlankBox: Semi-transparent layers with borders and rounded corners.[/center]

Link to comment
Share on other sites

  • 3 weeks later...
  • 1 month later...

i am working on an xml which for some reason has spaces in each of its values:

<add key="AddToAlerts" value="true" />

the udf works great as I am able to drill down and change values correctly, however the spaces are not retained.

and for some reason, the program that uses the xml needs those spaces otherwise it crashes.

i also noticed it removes blank lines... i appreciate the clean-up but i think spaces might be important in XML files?

here is a working xml snippet + script to illustrate:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <appSettings>
        <add key="production" value="true" />
        <add key="userInactivityTimeOut" value="144000000000" />
        <add key="AddToAlerts" value="true" />
        
        <!-- If provided, this is used as the session for Data connection
         Comment out to use the location specified during login -->
        
        <add key="offline.mode" value="false" />
    </appSettings>
</configuration>

#include <_XMLDomWrapper.au3>

    $file = "eh.xml"

    _XMLFileOpen($file)

    $aNodes = _XMLGetNodeCount("/configuration/appSettings/add")

    For $x = 1 To $aNodes
        $key = _XMLGetAttrib("/configuration/appSettings/add[" & $x & "]", "key")

        If $key = "userInactivityTimeOut" Then
            $timeout = _XMLGetAttrib("/configuration/appSettings/add[" & $x & "]", "value")

            If $timeout <> "144000000000" Then
                _XMLSetAttrib("/configuration/appSettings/add[" & $x & "]", "value", "144000000000")
            EndIf
        EndIf
    Next

any chance to retain whitespace?

aside from that works great! thanks for the great UDF =)

Edited by gcue
Link to comment
Share on other sites

  • 1 month later...

Hi AutoIT Forum ;)

First, sorry for my bad english. I hope you can understand me anyway.

I have different problems.

Here ist my AutoIT:

Func datentoxml()
  
   If GUICtrlRead($profil_auswahl) <> "Neues Profil anlegen" AND "Wählen Sie ein Profil aus" Then
   $o_DAS_Profil = $profil_auswahl
   ElseIf GUICtrlRead($profil_auswahl) = "Neues Profil anlegen" Then
   $o_DAS_Profil = $o_name
   EndIf
  
   $das_Profil = GUICtrlRead($o_DAS_Profil)
   $acc_name2 = GUICtrlRead($acc_name)
     
   $verschluesselt = _StringEncrypt (1, $i_benutzerpasswort, "test", 6)
    
   $sPath = @MyDocumentsDir & "profiles.xml" ;Verzeichnis der XML Datei.
  
   $root = "profiles" ;Name des Root Namens für die Eingabemaske
   $oprofiles = $root & "/o_profiles"
  
   $sXMLFile = _XMLCreateFile($sPath, $root, False)
   If @Error = 4 Then ;Error wenn die Datei schon besteht.
   MsgBox (0, "Error", "File exists")
   ElseIf @Error = 3 Then
   MsgBox (0, "Error", "File creation failed MSXML error")
   ElseIf @Error = 2 Then
   MsgBox (0, "Error", "No object")
   ElseIf @Error = 1 Then
   MsgBox (0, "Error", "Failed to create file")
   ElseIf @Error = 0 Then
   EndIf
   $file = _XMLFileOpen($sPath)
   _XMLNodeExists($oprofiles)
   If @error = 2 Then
   _XMLCreateChildNode ( $root, "o_profiles")
   ElseIf @error = 1 Then
   MsgBox (0, "XML Error", "No XML object @extended = 31."
   ElseIF @error = 0 Then  
   EndIf
   _XMLCreateChildNode ( $oprofiles, "name", GUICtrlRead($o_DAS_Profil))
  
   
   _XMLNodeExists($oprofiles & "/name/i")
   If @error = 2 Then
   _XMLCreateChildNode ( $oprofiles & "/name", "i")
   ElseIf @error = 1 Then
   MsgBox (0, "XML Error", "No XML object @extended = 31."
   ElseIF @error = 0 Then  
   EndIf
   _XMLCreateChildNode ( $oprofiles & "/name/i", "name", GUICtrlRead($acc_name))
   $acc_name = $oprofiles & "name/i/name"
  
   _XMLCreateChildNode ( $acc_name, "iserver", GUICtrlRead($i_server))
   _XMLCreateChildNode ( $acc_name, "username", GUICtrlRead($i_benutzername))
   _XMLCreateChildNode ( $acc_name, "password", $verschluesselt)
   _XMLCreateChildNode ( $acc_name, "sserver", GUICtrlRead($smtp_server))
  
EndFunc

I have some data and want to save it in a xml file.

I tried various things...to make it look like this:

<profiles>
<o_profiles>
  <name>Profile1
   <i>
    <name>INAME1
     <iserver>iserver</iserver>
     <username>username</username>
     <password>password</password>
     <sserver>sserver</sserver>
    </name>
    <name>INAME2
     <iserver>iserver</iserver>
     <username>username</username>
     <password>password</password>
     <sserver>sserver</sserver>
    </name>
    <name>INAME3
     <iserver>iserver</iserver>
     <username>username</username>
     <password>password</password>
     <sserver>sserver</sserver>
    </name>
   </i>
  </name>
  <name>Profile2
   <i>
    <name>INAME1
     <iserver>iserver</iserver>
     <username>username</username>
     <password>password</password>
     <sserver>sserver</sserver>
    </name>
    <name>INAME2
     <iserver>iserver</iserver>
     <username>username</username>
     <password>password</password>
     <sserver>sserver</sserver>
    </name>
    <name>INAME3
     <iserver>iserver</iserver>
     <username>username</username>
     <password>password</password>
     <sserver>sserver</sserver>
    </name>
   </i>
  </name>
</o_profiles>
</profiles>

1. It allways write's all <i> and the contant of <i> under the first <name>.

So how can it get path's to a Contant? like -> <name>Profile1...

I also need this to get Information out of a specific Profile or <i>.

2. At Point -> $sXMLFile = _XMLCreateFile($sPath, $root, False)

The DomWrapper shows a message when a file exist. But that stops my automation. So i cut it out of the DomWrapper by my selfe, but thats not the solution.

How can i get this done? I think of: Loading XML Data (if file exist) -> if file exist (delet) -> create new -> save data back to xml.

But how??

Thanks

Spenhouet

Link to comment
Share on other sites

  • 5 months later...

Hi,

Here is a problem, I would like to reproduce the xml file filezilla server

here's a start code

#Include <_XMLDomWrapper.au3>
$path = @ScriptDir&amp;"test.xml"
$root = "FileZillaServer"
_XMLCreateFile ($path, $root, True); create file with root data
$hXml= _XMLFileOpen($path)
_XMLCreateRootChild("Users", "" , "")

Dim $user = "ludo-rds"
Dim $Keys[1]
Dim $Values[1]

$Keys[0] = "Name"
$Values[0] = $user
_XMLCreateChildWAttr("//Users", "User", $Keys, $Values)

$Keys[0] = "Name"
$Values[0] = "Pass"


_XMLCreateChildNode("//User", "Option", " ", "")
_XMLSetAttrib($root&amp;"/Users/User/Option","Name", "Pass")

_XMLCreateChildNode("//User", "Option", " ", "")
_XMLSetAttrib($root&amp;"/Users/User/Option","Name", "Group")

resultat de mon XML:

<?xml version="1.0"?>

<FileZillaServer>

<Users>

<User Name="ludo-rds">

<Option Name="Group"> </Option>

<Option Name="Group"> </Option>

</User>

</Users>

</FileZillaServer>

xml file and a copy

<FileZillaServer>

<Users>

<User Name="ludo-rds">

<Option Name="Pass"></Option>

<Option Name="Group"></Option>

<Option Name="Bypass server userlimit">0</Option>

<Option Name="User Limit">0</Option>

<Option Name="IP Limit">0</Option>

<Option Name="Enabled">1</Option>

<Option Name="Comments"></Option>

<Option Name="ForceSsl">0</Option>

<IpFilter>

<Disallowed />

<Allowed />

</IpFilter>

<Permissions>

<Permission Dir="D:ludo-rds">

<Option Name="FileRead">1</Option>

<Option Name="FileWrite">0</Option>

<Option Name="FileDelete">0</Option>

<Option Name="FileAppend">0</Option>

<Option Name="DirCreate">0</Option>

<Option Name="DirDelete">0</Option>

<Option Name="DirList">1</Option>

<Option Name="DirSubdirs">1</Option>

<Option Name="IsHome">1</Option>

<Option Name="AutoCreate">0</Option>

</Permission>

</Permissions>

<SpeedLimits DlType="0" DlLimit="10" ServerDlLimitBypass="0" UlType="0" UlLimit="10" ServerUlLimitBypass="0">

<Download />

<Upload />

</SpeedLimits>

</User>

</Users>

</FileZillaServer>

thank you for your help Edited by ludoo
Link to comment
Share on other sites

@ludoo what is it exactly what you want to achieve with the FileZillaServer XML? If you just want to make changes on the xml, it's better to load a default FileZillaServer xml and then alter that with the function _XMLupdateField(xpath,data), instead of building it up.

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...