eltorro

XML DOM wrapper (COM)

778 posts in this topic

hi. links don't work for me (to download UDF). :think:

Share this post


Link to post
Share on other sites



hi. links don't work for me (to download UDF). :think:

Please try now. I migrated the server from windows and I believe all the permissions are now set correctly for all files. :(

Share this post


Link to post
Share on other sites

What's the difference between the MDI version and the Updated version? I mean, what do I have to download?

Share this post


Link to post
Share on other sites

Yessssss....It works!!!!....I figured out how to do _XMLUPDATEFIELD()...Thanks once again for the quick reply.

I copied and pasted both codes and it keeps saying:

C:\blablabla\_XMLDomWrapper.au3 (200) : ==> Variable must be of type "Object".:

$objNodeList = $objDoc.selectNodes ($strXPath)

$objNodeList = $objDoc^ ERROR

!>AutoIT3.exe ended.rc:2147483647

Share this post


Link to post
Share on other sites

What's the difference between the MDI version and the Updated version? I mean, what do I have to download?

The mdi version is able to work with more than one document.

I copied and pasted both codes and it keeps saying:

C:\blablabla\_XMLDomWrapper.au3 (200) : ==> Variable must be of type "Object".:

$objNodeList = $objDoc.selectNodes ($strXPath)

$objNodeList = $objDoc^ ERROR

!>AutoIT3.exe ended.rc:2147483647

What does your code look like???

Share this post


Link to post
Share on other sites

I copied and pasted both codes and it keeps saying:

C:\blablabla\_XMLDomWrapper.au3 (200) : ==> Variable must be of type "Object".:

$objNodeList = $objDoc.selectNodes ($strXPath)

$objNodeList = $objDoc^ ERROR

!>AutoIT3.exe ended.rc:2147483647

eltorro, i can confirm this error. i'm using the latest beta (3.1.1.126)

I wrote my own script, which failed, and then I tried some scripts in this thread. I also tried the example in the first post.

The exact location of the error changes depending on the function called.

When compiling the first-post example (which uses the non-MDI version), the error looks like:

C:\Documents and Settings\*\_XMLDomWrapper.au3 (363) : ==> Variable must be of type "Object".: 
$objNodeList = $objDoc.selectNodes ($strXPath & $strQuery) 
$objNodeList = $objDoc^ ERROR

When compiling the first-post example with the MDI version, the error looks like:

C:\Documents and Settings\*\_XMLMdiDOM.au3 (603) : ==> Object referenced outside a "With" statement.: 
$objNodeList = $objDoc[$oIndex].selectNodes ($strXPath & $strQuery) 
$objNodeList = $objDoc[$oIndex]^ ERROR

I'm really interested in this udf. It looks great. Keep up the good work!

Share this post


Link to post
Share on other sites

#67 ·  Posted (edited)

Can you provide your script ??

If you'd rather not post it, can you pm it to me???

eltorro, i can confirm this error. i'm using the latest beta (3.1.1.126)

I wrote my own script, which failed, and then I tried some scripts in this thread. I also tried the example in the first post.

The exact location of the error changes depending on the function called.

When compiling the first-post example (which uses the non-MDI version), the error looks like:

C:\Documents and Settings\*\_XMLDomWrapper.au3 (363) : ==> Variable must be of type "Object".: 
$objNodeList = $objDoc.selectNodes ($strXPath & $strQuery) 
$objNodeList = $objDoc^ ERROR

When compiling the first-post example with the MDI version, the error looks like:

C:\Documents and Settings\*\_XMLMdiDOM.au3 (603) : ==> Object referenced outside a "With" statement.: 
$objNodeList = $objDoc[$oIndex].selectNodes ($strXPath & $strQuery) 
$objNodeList = $objDoc[$oIndex]^ ERROR

I'm really interested in this udf. It looks great. Keep up the good work!

Edited by eltorro

Share this post


Link to post
Share on other sites

#68 ·  Posted (edited)

I think is because _XMLDomWrapper.au3 use in LoadXML function: ObjCreate("Msxml2.DOMdocument.4.0")

you have tu use 3.0 to make it work properly.

Edited by Juanse

Share this post


Link to post
Share on other sites

I uploaded an updated version of the save settings example, however the example script is in need of a re-write (at least it is need of some error checking) (CyberSlugs part is fine.)

There will also be some code updates to the wrapper. Mainly more error checking and a version check to see which com object is available for use ( if any).

Suggestions and colaberation would be welcome and greatly appreciated.

elTorro

p.s.

Some people may need to change the com object opened in the _XMLFileOpen function to

$objDoc = ObjCreate("Msxml2.DOMdocument.3.0")

;~ $objDoc = ObjCreate("Msxml2.DOMdocument.4.0")

lines 83,84 in the _XMLDomWrapper , lines 519,520 in then multi doc version.

Share this post


Link to post
Share on other sites

There will also be some code updates to the wrapper. Mainly more error checking and a version check to see which com object is available for use ( if any).

Suggestions and colaberation would be welcome and greatly appreciated.

I wanna help you. Send me a PM if you are interested in. I will send you my MSN in PM too.

Share this post


Link to post
Share on other sites

I wanna help you. Send me a PM if you are interested in. I will send you my MSN in PM too.

Thanks

eltorro

Share this post


Link to post
Share on other sites

First off this seems like a great job you've done.

Unfortunately I need help if someone has a spare moment. I have an xml that I cannot change it's format because another program accesses it and pulls information from it as is. I need to read the values from one of the field attrib's into an array or list. I also need to be able to copy the attrib values in a specific row of the xml into variables. I am able to get autoit to open the xml but from there I am lost.

I have alot of general computer knowledge(started coding on a comadore vic 20) but I have no experience with xml and every resource I have read through seemed to expect an understanding of xml organization before you read it. In short I got a massive headache. I'll post one of the xml's using the format I have to interact with so you know exactly what I'm dealing with. If anyone could tell me how to do what I need to or at lest point me to some fairly simple or beginners(in xml) guide to navigating xml data I would greatly appreciate it.

Once again sorry for the noob question and thanks for any help you can offer

cookbook.xml

Share this post


Link to post
Share on other sites

Not sure what kind of query that you are looking for. But he following code displays all the "ROWS". I'm sure that you have some criteria to narrow the query.

; ----------------------------------------------------------------------------
;
; AutoIt Version: 3.1.1.124
; Author:         Stephen Podhajecki eltorro <gehossafats@netmdc.com>
; Version: 0.1
;
; Script Function:
;
; ----------------------------------------------------------------------------
#Include "C:\Program Files\AutoIt3\Beta\include\_XMLDomWrapper.au3"; change this to your needs
#Include <Array.au3>
;_SetDebug(True)
opt("MustDeclareVars", 1)
;===============================================================================
Global $xmlFile
Global $count = 0
Global $sNxPath, $fHwnd
;===============================================================================

$xmlFile = FileOpenDialog("Open XML", @ScriptDir, "XML (*.XML)", 1)
If @error Then
    MsgBox(4096, "File Open", "No file chosen , Exiting")
    Exit
EndIf

Main()

Exit
;===============================================================================
;Funcs
;===============================================================================
Func Main()
    Local $szXPath, $aNodeName, $find, $ns, $oXSD,$iNodeCount,$aAttrName[1],$aAttrVal[1],$ret_val
    
    $ns = ""
    $oXSD = _XMLFileOpen ($xmlFile, $ns)
    If @error Or $oXSD < 1 Then
        MsgBox(0, "Error", "There was an error opening the file " & $xmlFile)
        $oXSD = 0
        Exit
    EndIf
    $szXPath = "//DATAPACKET/ROWDATA"
    $iNodeCount = _XMLGetNodeCount($szXPath & "/*")
    MsgBox(0,"Node Count",$iNodeCount)

    $aNodeName = _XMLGetChildNodes ($szXPath); get a list of node names under this path
    If $aNodeName <> - 1 Then
        For $find = 1 To $aNodeName[0]
            ConsoleWrite($aNodeName[$find]& '[' & $find & ']'&@LF)
            ;It's better to use node index instead of node name as all node here have same name.
          _XMLGetAllAttrib($szXPath & "/*" & '[' & $find & ']',$aAttrName,$aAttrVal)
             _ArrayDisplay($aAttrName,$szXPath & "/*" & '[' & $find & ']')
             _ArrayDisplay($aAttrVal,$szXPath & "/*" & '[' & $find & ']')

        Next
        MsgBox(266288,"_XMLWrapper","Done")
    Else
        MsgBox(0, "Error:", "No nodes found for " & $szXPath)
    EndIf
    $oXSD = 0
EndFunc;==>Main

First off this seems like a great job you've done.

Unfortunately I need help if someone has a spare moment. I have an xml that I cannot change it's format because another program accesses it and pulls information from it as is. I need to read the values from one of the field attrib's into an array or list. I also need to be able to copy the attrib values in a specific row of the xml into variables. I am able to get autoit to open the xml but from there I am lost.

I have alot of general computer knowledge(started coding on a comadore vic 20) but I have no experience with xml and every resource I have read through seemed to expect an understanding of xml organization before you read it. In short I got a massive headache. I'll post one of the xml's using the format I have to interact with so you know exactly what I'm dealing with. If anyone could tell me how to do what I need to or at lest point me to some fairly simple or beginners(in xml) guide to navigating xml data I would greatly appreciate it.

Once again sorry for the noob question and thanks for any help you can offer

Share this post


Link to post
Share on other sites

Thanks for the quick reply, I started to figure it out by studying the posts you made on page 2 about the drinks file. Main problem is/was a complete lack of knowledge on navigating the xml. Starting to figure it out somewhat. Main problem was not realising the indexing since there was no visible markers for it and not knowing the syntax/notation for the pathways in xml. Thanks you again for the help and your work on these functions :D

Share this post


Link to post
Share on other sites

#75 ·  Posted (edited)

Main problem was not realising the indexing since there was no visible markers for it and not knowing the syntax/notation for the pathways in xml. Thanks you again for the help and your work on these functions :D

Sometimes it's easier to think of an XML file as a directory structure or as a family tree.

Open the file in Firefox and see how it cascades out.

There's a link in my sig below to a script that opens an XML file in a treeview. It can give you an idea of what goes under what too.

Good Luck. :D

Here are some links that have helped me.

Learn XML

Learn XPath

Edited by eltorro

Share this post


Link to post
Share on other sites

When I create a file, it only writes to one line. Is there any formatting option to have carriage returns for each node?

Share this post


Link to post
Share on other sites

When I create a file, it only writes to one line. Is there any formatting option to have carriage returns for each node?

Unfortunately, not that I know of.

However, html tidy (not to be confused with tidy that comes with AutoIt) can do the job.

Place the binary in the SciTE folder( the same folder as scite.exe).

I added this to my html.properties file.

command.name.1.$(file.patterns.xml)=Save and Indent XML
command.1.$(file.patterns.xml)=tidy -xml -indent -modify "$(FilePath)"
command.is.filter.1.$(file.patterns.xml)=1
command.save.before.1.$(file.patterns.xml)=1

Then you should be able to load the xml file in SciTE, navigate to the tool menu and find "Save and Indent XML" . Select it and format away.

Hope that helps

eltorro

Share this post


Link to post
Share on other sites

Well here is what I came up with.

First I modified _XMLCreateFile

Func _XMLCreateFile($strPath, $strRoot, $bOverwrite = False,$bUTF8 = False)
    Local $retval, $fe, $objPI, $objDoc, $rootElement
    $fe = FileExists($strPath)
    If $fe And Not $bOverwrite Then
        $retval = (MsgBox(4097, "File Exists:", "The specified file exits." & @CRLF & "Click OK to overwrite file or cancel to exit."))
        If $retval = 1 Then
            FileCopy($strPath, $strPath & @YEAR & "-" & @MON & "-" & @MDAY & "_" & @HOUR & "-" & @MIN & "-" & @SEC & ".bak", 1)
            FileDelete($strPath)
            $fe = False
        Else
            _XMLSetError( "Error failed to create file: " & $strPath & @CRLF & "File exists.")
            SetError(1)
            Return -1
        EndIf
    Else
        FileCopy($strPath, $strPath & ".old", 1)
        FileDelete($strPath)
        $fe = False
    EndIf
    
    If $fe = False Then
        ;==== pick your poison
        $objDoc = ObjCreate("Msxml2.DOMdocument.4.0")
        if not IsObj($objDoc) Then  $objDoc = ObjCreate("Msxml2.DOMdocument.3.0")
        if not IsObj($objDoc) Then  $objDoc = ObjCreate("Microsoft.XMLDOM")
        if not IsObj($objDoc) Then 
            MsgBox(266288,"XML Error","Unable to instantiate the XML object"&@LF&"Please check your components.")
            return -1
        EndIf
        ;MsgBox(266288,"XML Wrapper",ObjName($objDoc,4))

        If $bUTF8 Then 
            $objPI = $objdoc.createProcessingInstruction ("xml", "version=""1.0"" encoding=""UTF-8""")
        Else
            $objPI = $objDoc.createProcessingInstruction ("xml", "version=""1.0""")
        EndIf
    
        $objDoc.appendChild ($objPI)
        $rootElement = $objDoc.createElement ($strRoot)
        $objDoc.documentElement = $rootElement
        
        ;ADD CARRIAGE RETURN <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        $objFORMAT = $objDoc.createTextNode(@CRLF)
        $objDoc.documentElement.appendChild ($objFORMAT)
        
        $objDoc.save ($strPath)
        If $objDoc.parseError.errorCode <> 0 Then
            ;           _XMLSetError( "Error Creating specified file: " & $strPath & @CRLF & $oMyError.windescription)
            _XMLSetError( "Error Creating specified file: " & $strPath)
            SetError($objDoc.parseError.errorCode)
            Return -1
        EndIf
        Return
    Else
        _XMLSetError( "Error! Failed to create file: " & $strPath)
        SetError(1)
        Return -1
    EndIf
    Return 1
EndFunc   ;==>_XMLCreateFile
oÝ÷ Ù8^¨v'âyÖ×0°«y«^F-6^Xm¯öÚºÚ"µÍ[ÈÖSÜX]TÛÝÙUÐ]    ÌÍÜÝÙK ÌÍØP]    ÌÍØU[    ÌÍÜÝ]HH ][ÝÉ][ÝË    ÌÍÜÝ[YTÜÈH    ][ÝÉ][ÝÊBSØØ[ ÌÍÛØÚ[ ÌÍÛØ]   ÌÍÛØ][IÌÍÛØÚ[H ÌÍÛØØËÜX]SÙH
    ÌÍÓÑWÑSSQS ÌÍÜÝÙK ÌÍÜÝ[YTÜÊBBRY ÌÍÜÝ]H  ÉÝÈ  ][ÝÉ][ÝÈ[   ÌÍÛØÚ[^H   ÌÍÜÝ]BNÂRYÜH[UÚ[HÜHBRYÐ^J  ÌÍØP]H[Ð^J  ÌÍØU[
H[BBNÒYPÝ[
    ÌÍØP]KSÝ[
    ÌÍØP]H   ÉÝÈPÝ[
    ÌÍØU[
KSÝ[
    ÌÍØU[
H[ÈÈÝ[ÝÜÏÂBBRYPÝ[
    ÌÍØP]H   ÉÝÈPÝ[
    ÌÍØU[
H[BBBWÖSÙ]Ü  ][ÝÐ]X]H[[YHZÛX]Ú   ][ÝÈ  [ÈÔ   [È ][ÝÔXÙHXZÙHÝHXXÚ]X]HÈHX]Ú[È[YK][ÝÊBBBBTÙ]ÜBBBBT]LBBBQ[ÙBBBBSØØ[ ÌÍÚBBBBNÑÜ ÌÍÚHHÝ[
    ÌÍØP]HÈPÝ[
    ÌÍØP]NÈÈÝ[ÝÜÏÂBBBQÜ  ÌÍÚHHÈPÝ[
    ÌÍØP]HHBBBBBRY   ÌÍØP]ÉÌÍÚWHH ][ÝÉ][ÝÈ[BBBBBWÖSÙ]Ü ][ÝÑÜÜX][ÈÚ[ÙN   ][ÝÈ  [È ÌÍÜÝÙH [ÈÔ   [È ][ÝÈ]X]H[YHØ[ÝHS][ÝÈ  [ÈÔBBBBBBTÙ]ÜJBBBBBBT]LBBBBBQ[YßBBBBBZY    ÌÍØU[ÉÌÍÚWHHÚ
H[ßBBBBBBWÖSÙ]Ü ][ÝÑÜÜX][ÈÚ[ÙN   ][ÝÈ  [È ÌÍÜÝÙH [ÈÔ   [É][ÝÈ]X]H[YHØ[ÝHS][ÝÈ   [ÈÔBßBBBBBBTÙ]ÜJBßBBBBBBT]LBßBBBBBQ[YBBBBBBBBBIÌÍÛØ]H    ÌÍÛØØËÜX]P]X]H
    ÌÍØP]ÉÌÍÚWJNË   ÌÍÜÝ[YTÜÊBBBBBIÌÍÛØ][H    ÌÍÛØØËÜX]U^ÙH
    ÌÍØU[ÉÌÍÚWJBBBBBIÌÍÛØ][Ú[
    ÌÍÛØ][
BBBBBIÌÍÛØÚ[Ù]]X]H
    ÌÍØP]ÉÌÍÚWK  ÌÍØU[ÉÌÍÚWJBBBBS^BBQ[YBQ[ÙBBBIÌÍÛØ]H    ÌÍÛØØËÜX]P]X]H
    ÌÍØP]BBBIÌÍÛØ][H ÌÍÛØØËÜX]U^ÙH
    ÌÍØU[
BBBIÌÍÛØ][Ú[
    ÌÍÛØ][
BBBIÌÍÛØÚ[Ù]]X]H
    ÌÍØP]    ÌÍØU[
BBQ[YBIÌÍÛØØËØÝ[Y[[[Y[[Ú[
    ÌÍÛØÚ[
BBBBNÐQÐTPQÑHUT  ÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÂBIÌÍÛØÔPUH ÌÍÛØØËÜX]U^ÙJÔBBIÌÍÛØØËØÝ[Y[[[Y[[Ú[
    ÌÍÛØÔPU
BBBBIÌÍÛØØËØ]H
    ÌÍÜÝ[JBBIÌÍÛØÚ[H   ][ÝÉ][ÝÂBT]BNÂQ[ÙBUÑ[NÂWÖSÙ]Ü    ][ÝÑZ[YÈÜX]HÛÝÚ[Ú]]X]Î ][ÝÈ  [È ÌÍÜÝÙH [ÈÔ   [È ÌÍÛÓ^QÜÚ[ØÜ[ÛBWÖSÙ]Ü    ][ÝÑZ[YÈÜX]HÛÝÚ[Ú]]X]Î ][ÝÈ  [È ÌÍÜÝÙH [ÈÔBTÙ]ÜJBT]LBNÂQ[Y[[ÈÏOIÝ×ÖSÜX]TÛÝÙUÐ]

And this works pretty well. The only strange thing is that an extra indent is always added to the first child element.

Nice job with this UDF though it works well out of the box but I need the hierarchial appearance so the file can be edited by a human if need be. I will try to add indenting to the child elements as well.

Thanks

Share this post


Link to post
Share on other sites

Eltoro, did you actually run the code you posted for my problem with the xml I posted? Because when I try it I get a error opening the file. When I use the path from your code in a test snippet of code which does open the file I get a error stating the variable must be an object. Thanks for the help and I am continuing to plug at it.

Share this post


Link to post
Share on other sites

Eltoro, did you actually run the code you posted for my problem with the xml I posted? Because when I try it I get a error opening the file. When I use the path from your code in a test snippet of code which does open the file I get a error stating the variable must be an object. Thanks for the help and I am continuing to plug at it.

Yes, I did. :D

Please post your code.

Share this post


Link to post
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