toasterking

Subsonic jukebox control

1 post in this topic

#1 ·  Posted (edited)

Here is the result of my playing around with Subsonic's REST API tonight.  This script searches for a song in the Subsonic library, queues it in the jukebox playlist, starts it playing on the server, then stops it and clears the playlist.  This requires Subsonic.  At present, they include the REST API that this script uses in the 30-day trial, but then it goes away unless you upgrade to Subsonic Premium.

Change the variables at the beginning to represent your server URL and user account.  (My server happened to be running on the same machine on port 85.)  The account must exist in Subsonic and must have permission to play files in jukebox mode (which is not a default permission).  Lastly, you probably want to change the parameters in the _SubsonicJukeboxAddSong function call to represent a song that is actually on the server.

#cs ----------------------------------------------------------------------------

    AutoIt Version: 3.3.12.0
    Author:         ToasterKing

    Script Function:


#ce ----------------------------------------------------------------------------
#Region ; --- Include files
#include <Array.au3>
#include <FileConstants.au3>
#include <StringConstants.au3>
#include <_XMLDomWrapper.au3>
#EndRegion ; --- Include files


Global $sSubsonicAddr = "http://localhost:85"
Local $sSubsonicJukeboxName = "BlabberBox"
Local $sSubsonicUsername = "jukeboxuser"
Local $sSubsonicPassword = "j00kthis!"
Global $sSubsonicBaseParams = "u=" & $sSubsonicUsername & "&p=" & $sSubsonicPassword & "&c=" & $sSubsonicJukeboxName


; Add a song to the jukebox playlist
_SubsonicJukeboxAddSong("catch a fire","haddaway")
; Start playing
_SubsonicCmd($sSubsonicAddr & "/rest/jukeboxControl.view?" & $sSubsonicBaseParams & "&v=1.10.2&action=start")
; Wait
Sleep(15000)
For $x = 1 To 5
    If _SubsonicJukeboxIsPlaying() Then
        MsgBox(0,"","Subsonic jukebox is still playing!",2)
    Else
        MsgBox(0,"","Subsonic jukebox is no longer playing.",2)
        Exit
    EndIf
    If $x = 3 Then _SubsonicCmd($sSubsonicAddr & "/rest/jukeboxControl.view?" & $sSubsonicBaseParams & "&v=1.10.2&action=clear") ; Clear playlist and stop playing
    Sleep(5000)
Next


; #FUNCTION# ====================================================================================================================
; Name ..........: _SubsonicCmd
; Description ...: Makes a general REST API request.
; Syntax ........: _SubsonicCmd($sRequest)
; Parameters ....: $sRequest            - The complete request URL.
; Return values .: Success:  1
;                  Failure:  0 and sets @error to 1
; Author ........: Your Name
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _SubsonicCmd($sRequest)
    Local $bSubsonicResult,$sSubsonicResult,$sSubsonicReqStatus
    ConsoleWrite("Sending REST API request: " & $sRequest & @CRLF)
    $bSubsonicResult = InetRead($sRequest,1)
    If @error Then
        ConsoleWrite("Error " & @error & " in InetRead." & @CRLF)
        Return SetError(1,0,"")
    EndIf
    $sSubsonicResult = BinaryToString($bSubsonicResult,4) ; Convert the XML response to a string so it can be parsed
;~  ConsoleWrite("REST API response from Subsonic:" & @CRLF & $sSubsonicResult & @CRLF)
    ; Remove the first "xmlns" attribute for the namespace because I can't figure out how to make the XML parse otherwise
    Local $iToRemovePosStart = StringInStr($sSubsonicResult," xmlns=""")
    Local $iToRemovePosEnd = StringInStr($sSubsonicResult,"""",0,1,$iToRemovePosStart + 8)
    Local $sSubsonicResultEdited = StringLeft($sSubsonicResult,$iToRemovePosStart - 1) & StringTrimLeft($sSubsonicResult,$iToRemovePosEnd)
    ConsoleWrite("REST API response from Subsonic after editing:" & @CRLF & StringStripWS($sSubsonicResultEdited,$STR_STRIPTRAILING) & @CRLF)
;~  _Setdebug(True) ; Turn on XML debugging
    _XMLLoadXML($sSubsonicResultEdited) ; Load the XML response for parsing
    If @error Then
        ConsoleWrite("Error " & @error & " in _XMLLoadXML" & @CRLF)
        Return SetError(1,0,"")
    EndIf
    ConsoleWrite("Using MSXML version " &   _XMLGetDomVersion() & " for parsing." & @CRLF)
    $sSubsonicReqStatus = _XMLGetAttrib("//subsonic-response","status") ; Get the "status" attribute to see if the command worked.
    If $sSubsonicReqStatus = "ok" Then
        ConsoleWrite("The REST API returned success for this request!" & @CRLF)
    Else
        ConsoleWrite("Status 'ok' not found in response!  See the debug entries for the full XML response." & @CRLF)
        Return SetError(1,0,"")
    EndIf
    Return SetError(0,0,1) ; Success!
EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _SubsonicJukeboxAddSong
; Description ...: Searches for a song on the Subsonic server and adds it/them to the jukebox playlist.
; Syntax ........: _SubsonicJukeboxAddSong($sSong[, $sArtist = ""[, $sAlbum = ""[, $iSongsToAddMax = 1]]])
; Parameters ....: $sSong               - Complete, exact name of the song to find (case insensitive)
;                  $sArtist             - [optional] Complete name of the artist name to match (case insensitive)
;                  $sAlbum              - [optional] Complete name of the album name to match (case insensitive)
;                  $iSongsToAddMax      - [optional] Maximum number of songs to match and add to the playlist. Default is 1.
;                                         0 means no limit, although there is a hardcoded limit on number of search results
;                                         returned in the function.
; Return values .: Success:  1
;                  Failure:  0 and sets @error:
;                    1 - General error (check the log)
;                    2 - Zero search results
; Author ........: ToasterKing
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _SubsonicJukeboxAddSong($sSong,$sArtist = "",$sAlbum = "",$iSongsToAddMax = 1)
    Local $bSubsonicResult,$sSubsonicResult,$sRequest,$sSubsonicReqStatus
    ConsoleWrite("Searching for requested song '" & $sSong & "', artist '" & $sArtist & "', album '" & $sAlbum & "'." & @CRLF)
    ; Assemble the request URL (note: hardcoded here to 50 search results)
    $sRequest = $sSubsonicAddr & "/rest/search3.view?" & $sSubsonicBaseParams & "&v=1.10.2&query=%22" & _URLEncode($sSong) & "%22&songCount=50&artistCount=0&albumCount=0"
    ConsoleWrite("Sending REST API request: " & $sRequest & @CRLF)
    ; Make the HTTP request
    $bSubsonicResult = InetRead($sRequest,1)
    If @error Then
        ConsoleWrite("Error " & @error & " in InetRead." & @CRLF)
        Return SetError(1,0,"")
    EndIf
    $sSubsonicResult = BinaryToString($bSubsonicResult,4) ; Convert the XML response to a string so it can be parsed
;~  ConsoleWrite("REST API response from Subsonic:" & @CRLF & $sSubsonicResult & @CRLF)
    ; Remove the first "xmlns" attribute for the namespace because I can't figure out how to make the XML parse otherwise
    Local $iToRemovePosStart = StringInStr($sSubsonicResult," xmlns=""")
    Local $iToRemovePosEnd = StringInStr($sSubsonicResult,"""",0,1,$iToRemovePosStart + 8)
    Local $sSubsonicResultEdited = StringLeft($sSubsonicResult,$iToRemovePosStart - 1) & StringTrimLeft($sSubsonicResult,$iToRemovePosEnd)
    ConsoleWrite("REST API response from Subsonic after editing:" & @CRLF & StringStripWS($sSubsonicResultEdited,$STR_STRIPTRAILING) & @CRLF)
;~  _Setdebug(True) ; Turn on XML debugging
    _XMLLoadXML($sSubsonicResultEdited) ; Load the XML response for parsing
    If @error Then
        ConsoleWrite("Error " & @error & " in _XMLLoadXML" & @CRLF)
        Return SetError(1,0,"")
    EndIf
    ConsoleWrite("Using MSXML version " &   _XMLGetDomVersion() & " for parsing." & @CRLF)
    $sSubsonicReqStatus = _XMLGetAttrib("//subsonic-response","status") ; Get the "status" attribute to see if the command worked.
    If $sSubsonicReqStatus = "ok" Then
        ConsoleWrite("The REST API returned success for this request!" & @CRLF)
    Else
        ConsoleWrite("Status 'ok' not found in response!  See the debug entries for the full XML response." & @CRLF)
        Return SetError(1,0,"")
    EndIf
    ; Get ready to loop through all the search results.
    Dim $aAttrName[1], $aAttrValue[1], $aStats[0][5], $iCurrentId, $iSongMatched = 0
    for $x = 1 to 5000
        _XMLGetAllAttrib ("//subsonic-response/searchResult3/*["&$x&"]",$aAttrName,$aAttrValue ); by index, show all attribs. xml indexes are 0 based.
        if @error Then ExitLoop ; No more results found.
;~      _ArrayDisplay($aAttrName,"Attrib Names")
;~      _ArrayDisplay($aAttrValue,"Attrib Value")
        $iCurrentId = _XMLGetAttrib("//subsonic-response/searchResult3/*["&$x&"]","id") ; Get the ID attribute of the current search result.
        ; Compare song of the attributes of the search result to the ones specified.
        If _XMLGetAttrib("//subsonic-response/searchResult3/*["&$x&"]","type") = "music" And _
          _XMLGetAttrib("//subsonic-response/searchResult3/*["&$x&"]","title") = $sSong And _
          ($sArtist = "" Or _XMLGetAttrib("//subsonic-response/searchResult3/*["&$x&"]","artist") = $sArtist) And _
          ($sAlbum = "" Or _XMLGetAttrib("//subsonic-response/searchResult3/*["&$x&"]","album") = $sAlbum) And _
          _XMLGetAttrib("//subsonic-response/searchResult3/*["&$x&"]","type") = "music" Then
            ConsoleWrite("Song " & $iCurrentId & " matches the criteria." & @CRLF)
            $iSongMatched += 1 ; Increment the counter
            If _SubsonicCmd($sSubsonicAddr & "/rest/jukeboxControl.view?" & $sSubsonicBaseParams & "&v=1.10.2&action=add&id=" & $iCurrentId) Then
                ConsoleWrite("Song " & $iCurrentId & " added to the jukebox playlist." & @CRLF)
            Else
                ConsoleWrite("Song " & $iCurrentId & " could not be added to the jukebox playlist." & @CRLF)
            EndIf
            If $iSongsToAddMax > 0 And $iSongMatched >= $iSongsToAddMax Then ExitLoop ; If the number of matching songs to add has been satisfied, stop adding.
        Else
            ConsoleWrite("Song " & $iCurrentId & " doesn't match the criteria; continuing." & @CRLF)
        EndIf
    next
    If $iSongMatched Then
        Return SetError(0,0,1)
    Else
        ConsoleWrite("No songs were found matching the criteria." & @CRLF)
        Return SetError(2,0,0)
    EndIf
EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _SubsonicJukeboxIsPlaying
; Description ...: Check whether Subsonic jukebox is playing music.
; Syntax ........: _SubsonicJukeboxIsPlaying()
; Parameters ....:
; Return values .: Success: 1 - Playing
;                           0 - Paused/stopped
;                  Failure: 0 and sets @error to 1.
; Author ........: ToasterKing
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _SubsonicJukeboxIsPlaying()
    Local $bSubsonicResult,$sSubsonicResult,$sRequest,$sSubsonicReqStatus
    ConsoleWrite("Querying whether Subsonic jukebox is playing." & @CRLF)
    ; Assemble the request URL (note: hardcoded here to 50 search results)
    $sRequest = $sSubsonicAddr & "/rest/jukeboxControl.view?" & $sSubsonicBaseParams & "&v=1.10.2&action=status"
    ConsoleWrite("Sending REST API request: " & $sRequest & @CRLF)
    ; Make the HTTP request
    $bSubsonicResult = InetRead($sRequest,1)
    If @error Then
        ConsoleWrite("Error " & @error & " in InetRead." & @CRLF)
        Return SetError(1,0,"")
    EndIf
    $sSubsonicResult = BinaryToString($bSubsonicResult,4) ; Convert the XML response to a string so it can be parsed
;~  ConsoleWrite("REST API response from Subsonic:" & @CRLF & $sSubsonicResult & @CRLF)
    ; Remove the first "xmlns" attribute for the namespace because I can't figure out how to make the XML parse otherwise
    Local $iToRemovePosStart = StringInStr($sSubsonicResult," xmlns=""")
    Local $iToRemovePosEnd = StringInStr($sSubsonicResult,"""",0,1,$iToRemovePosStart + 8)
    Local $sSubsonicResultEdited = StringLeft($sSubsonicResult,$iToRemovePosStart - 1) & StringTrimLeft($sSubsonicResult,$iToRemovePosEnd)
    ConsoleWrite("REST API response from Subsonic after editing:" & @CRLF & StringStripWS($sSubsonicResultEdited,$STR_STRIPTRAILING) & @CRLF)
;~  _Setdebug(True) ; Turn on XML debugging
    _XMLLoadXML($sSubsonicResultEdited) ; Load the XML response for parsing
    If @error Then
        ConsoleWrite("Error " & @error & " in _XMLLoadXML" & @CRLF)
        Return SetError(1,0,"")
    EndIf
    ConsoleWrite("Using MSXML version " &   _XMLGetDomVersion() & " for parsing." & @CRLF)
    $sSubsonicReqStatus = _XMLGetAttrib("//subsonic-response","status") ; Get the "status" attribute to see if the command worked.
    If $sSubsonicReqStatus = "ok" Then
        ConsoleWrite("The REST API returned success for this request!" & @CRLF)
    Else
        ConsoleWrite("Status 'ok' not found in response!  See the debug entries for the full XML response." & @CRLF)
        Return SetError(1,0,"")
    EndIf
    If _XMLGetAttrib("//subsonic-response/jukeboxStatus","playing") = "true" Then
        ConsoleWrite("Subsonic Jukebox is playing." & @CRLF)
        Return SetError(0,0,1)
    Else
        ConsoleWrite("Subsonic Jukebox is not playing." & @CRLF)
        Return SetError(0,0,0)
    EndIf
EndFunc

;===============================================================================
; _URLEncode()
; Description: : Encodes a string to be URL-friendly
; Parameter(s): : $toEncode - The String to Encode
; : $encodeType = 0 - Practical Encoding (Encode only what is necessary)
; : = 1 - Encode everything
; : = 2 - RFC 1738 Encoding - http://www.ietf.org/rfc/rfc1738.txt
; Return Value(s): : The URL encoded string
; Author(s): : nfwu
; Note(s): : -
;
;===============================================================================
Func _URLEncode($toEncode, $encodeType = 0)
    Local $strHex = "", $iDec
    Local $aryChar = StringSplit($toEncode, "")
    If $encodeType = 1 Then;;Encode EVERYTHING
        For $i = 1 To $aryChar[0]
            $strHex = $strHex & "%" & Hex(Asc($aryChar[$i]), 2)
        Next
        Return $strHex
    ElseIf $encodeType = 0 Then;;Practical Encoding
        For $i = 1 To $aryChar[0]
            $iDec = Asc($aryChar[$i])
            if $iDec <= 32 Or $iDec = 37 Then
                $strHex = $strHex & "%" & Hex($iDec, 2)
            Else
                $strHex = $strHex & $aryChar[$i]
            EndIf
        Next
        Return $strHex
    ElseIf $encodeType = 2 Then;;RFC 1738 Encoding
        For $i = 1 To $aryChar[0]
            If Not StringInStr("$-_.+!*'(),;/?:@=&abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", $aryChar[$i]) Then
                $strHex = $strHex & "%" & Hex(Asc($aryChar[$i]), 2)
            Else
                $strHex = $strHex & $aryChar[$i]
            EndIf
        Next
        Return $strHex
    EndIf
EndFunc

This script uses _XMLDomWrapper.au3 by Stephen Podhajecki.  Since it's been a bit hard to track down a working link to this in the past, I've just included the version I used here.

 
#include-once
; #INDEX# ======================================================================
; Title .........: _XMLDomWrapper
; AutoIt Version : 3.2.3++
; Language ......: English
; Description ...: Functions to use for reading and writing XML using msxml.
; Author ........: Stephen Podhajecki Eltorro
; ==============================================================================
; XML DOM Wrapper functions

#cs defs to add to au3.api
    _XMLCreateFile           Creates an XML file with the given name and root.
    _XMLFileOpen             Creates an instance of an XML file.
    _XMLSaveDoc              Save the xml doc,  use $iForce = 1 to force save if AutoSave is off.
    ; ==========================================================================
    _XMLGetChildNodes        Selects XML child Node(s) of an element based on XPath input from root node.
    _XMLGetNodeCount         Get node count for specified path and type.
    _XMLGetPath              Returns a nodes full path based on XPath input from root node.
    ; ==========================================================================
    _XMLSelectNodes          Selects XML Node(s) based on XPath input from root node.
    _XMLGetField             Get XML Field(s) based on XPath input from root node.
    _XMLGetValue             Get XML Field based on XPath input from root node.
    _XMLGetChildText         Selects XML child Node(s) of an element based on XPath input from root node.
    _XMLUpdateField          Update existing node(s) based on XPath specs.
    _XMLReplaceChild         Replaces a node with a new node.
    ; ==========================================================================
    _XMLDeleteNode           Delete specified XPath node.
    _XMLDeleteAttr           Delete attribute for specified XPath
    _XMLDeleteAttrNode       Delete attribute node for specified XPath
    ; ==========================================================================
    _XMLGetAttrib            Get XML attribute based on XPath input from root node.
    _XMLGetAllAttrib         Get all XML Field(s) attributes based on XPath input from root node.
    _XMLGetAllAttribIndex    Get all XML Field(s) attributes based on Xpathn and specific index.
    _XMLSetAttrib            Set XML Field(s) attributes based on XPath input from root node.
    ; ==========================================================================
    _XMLCreateCDATA          Create a CDATA SECTION node directly under root.
    _XMLCreateComment        Create a COMMENT node at specified path.
    _XMLCreateAttrib         Creates an attribute for the specified node.
    ; ==========================================================================
    _XMLCreateRootChild      Create node directly under root.
    _XMLCreateRootNodeWAttr  Create a child node under root node with attributes.
    _XMLCreateChildNode      Create a child node under the specified XPath Node.
    _XMLCreateChildWAttr     Create a child node under the specified XPath Node with Attributes.
    ; ==========================================================================
    _XMLSchemaValidate       Validate a document against a DTD.
    _XMLGetDomVersion        Returns the XSXML version currently in use.
    _XMLError                Sets or Gets XML error message generated by XML functions.
    _XMLUDFVersion           Returns the UDF Version number.
    _XMLTransform            Transfroms the document using built-in sheet or xsl file passed to function.
    _XMLNodeExists           Checks for the existence of the specified path.
    ; ==========================================================================
    _XMLSetAutoFormat        Turn auto indenting on or off.
    _XMLSetAutoSave          Set the automatic save to on or off.
#ce

; #VARIABLES# ==================================================================
Global Const $_XMLUDFVER = "1.0.3.97"
Global Const $NODE_ELEMENT = 1
Global Const $NODE_ATTRIBUTE = 2
Global Const $NODE_TEXT = 3
Global Const $NODE_CDATA_SECTION = 4
Global Const $NODE_ENTITY_REFERENCE = 5
Global Const $NODE_ENTITY = 6
Global Const $NODE_PROCESSING_INSTRUCTION = 7
Global Const $NODE_COMMENT = 8
Global Const $NODE_DOCUMENT = 9
Global Const $NODE_DOCUMENT_TYPE = 10
Global Const $NODE_DOCUMENT_FRAGMENT = 11
Global Const $NODE_NOTATION = 12
Global $strFile
Global $oXMLMyError ;COM error handler OBJ ; Initialize SvenP 's error handler
Global $sXML_error
Global $fDEBUGGING
Global $DOMVERSION = -1
Global $objDoc
Global $fXMLAUTOSAVE = True ;auto save updates
Global $fADDFORMATTING = True ;auto indent
; ==============================================================================

; #FUNCTION# ===================================================================
; Name ..........: _XMLFileOpen
; Description ...: Creates an instance of an XML file.
; Syntax.........:  _XMLFileOpen($strXMLFile[, $strNameSpc = ""[, $iVer = -1[, $fValOnParse = True]]])
; Parameters ....: $strXMLFile    - the XML file to open
;                  $strNameSpc    - the namespace to specifiy if the file uses one.
;                  $iVer          - specifically try to use the version supplied here.
;                  $fValOnParse   - validate the document as it is being parsed
; Return values .: Success        - 1
;                  Failure        - -1 and set @error to:
;                  |0 - No error
;                  |1 - Parse error, @Extended = MSXML reason
;                  |2 - No object
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLFileOpen($strXMLFile, $strNameSpc = "", $iVer = -1, $fValOnParse = True)
    ;==== pick your poison
    If $iVer <> -1 Then
        If $iVer > -1 And $iVer < 7 Then
            $objDoc = ObjCreate("Msxml2.DOMDocument." & $iVer & ".0")
            If IsObj($objDoc) Then
                $DOMVERSION = $iVer
            EndIf
        Else
            MsgBox(266288, "Error:", "Failed to create object with MSXML version " & $iVer)
            SetError(1)
            Return 0
        EndIf
    Else
        For $x = 8 To 0 Step -1
            If FileExists(@SystemDir & "\msxml" & $x & ".dll") Then
                $objDoc = ObjCreate("Msxml2.DOMDocument." & $x & ".0")
                If IsObj($objDoc) Then
                    $DOMVERSION = $x
                    ExitLoop
                EndIf
            EndIf
        Next
    EndIf
    If Not IsObj($objDoc) Then
        _XMLError("Error: MSXML not found. This object is required to use this program.")
        SetError(2)
        Return -1
    EndIf
    ;Thanks Lukasz Suleja
    $oXMLMyError = ObjEvent("AutoIt.Error")
    If $oXMLMyError = "" Then
        $oXMLMyError = ObjEvent("AutoIt.Error", "_XMLCOMEerr") ; ; Initialize SvenP 's error handler
    EndIf
    $strFile = $strXMLFile
    $objDoc.async = False
    $objDoc.preserveWhiteSpace = True
    $objDoc.validateOnParse = $fValOnParse
    If $DOMVERSION > 4 Then $objDoc.setProperty("ProhibitDTD", False)
    $objDoc.Load($strFile)
    $objDoc.setProperty("SelectionLanguage", "XPath")
    $objDoc.setProperty("SelectionNamespaces", $strNameSpc)
    If $objDoc.parseError.errorCode > 0 Then ConsoleWrite($objDoc.parseError.reason & @LF)
    If $objDoc.parseError.errorCode <> 0 Then
        _XMLError("Error opening specified file: " & $strXMLFile & @CRLF & $objDoc.parseError.reason)
        ;Tom Hohmann 2008/02/29
        SetError(1, $objDoc.parseError.errorCode, -1)
        $objDoc = 0
        Return -1
    EndIf
    ;Tom Hohmann 2008/02/29
    Return 1
EndFunc   ;==>_XMLFileOpen
;
; #FUNCTION# ===================================================================
; Name ..........: _XMLLoadXML
; Description ...: Creates an instance for a string of XML .
; Syntax.........:  _XMLLoadXML($strXML[,$strNameSpc=""[, $iVer = -1[, $fValOnParse = True]]])
; Parameters ....: $strXML        - The XML to load into the document
;                  $strNameSpc    - the namespace to specifiy if the file uses one.
;                  $iVer          - specifically try to use the version supplied here.
;                  $fValOnParse   - Set the MSXML ValidateOnParse property
; Return values .: Success        - 1
;                  Failure        - -1 and set @error to
;                  |1 - failed to create object, @Extended = MSXML reason
;                  |2 - no object found (MSXML required for _XML functions
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>,Lukasz Suleja,Tom Hohmann
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLLoadXML($strXML, $strNameSpc = "", $iVer = -1, $fValOnParse = True)
    If $iVer <> -1 Then
        If $iVer > -1 And $iVer < 7 Then
            $objDoc = ObjCreate("Msxml2.DOMDocument." & $iVer & ".0")
            If IsObj($objDoc) Then
                $DOMVERSION = $iVer
            EndIf
        Else
            MsgBox(266288, "Error:", "Failed to create object with MSXML version " & $iVer)
            SetError(1)
            Return 0
        EndIf
    Else
        For $x = 8 To 0 Step -1
            If FileExists(@SystemDir & "\msxml" & $x & ".dll") Then
                $objDoc = ObjCreate("Msxml2.DOMDocument." & $x & ".0")
                If IsObj($objDoc) Then
                    $DOMVERSION = $x
                    ExitLoop
                EndIf
            EndIf
        Next
    EndIf
    If Not IsObj($objDoc) Then
        _XMLError("Error: MSXML not found. This object is required to use this program.")
        SetError(2)
        Return -1
    EndIf
    ;Thanks Lukasz Suleja
    $oXMLMyError = ObjEvent("AutoIt.Error")
    If $oXMLMyError = "" Then
        $oXMLMyError = ObjEvent("AutoIt.Error", "_XMLCOMEerr") ; ; Initialize SvenP 's error handler
    EndIf
    $objDoc.async = False
    $objDoc.preserveWhiteSpace = True
    $objDoc.validateOnParse = $fValOnParse
    If $DOMVERSION > 4 Then $objDoc.setProperty("ProhibitDTD", False)
    $objDoc.LoadXml($strXML)
    $objDoc.setProperty("SelectionLanguage", "XPath")
    $objDoc.setProperty("SelectionNamespaces", $strNameSpc); "xmlns:ms='urn:schemas-microsoft-com:xslt'"
    If $objDoc.parseError.errorCode <> 0 Then
        _XMLError("Error loading the XML data: " & @CRLF & $objDoc.parseError.reason)
        ;Tom Hohmann 2008/02/29
        SetError(1, $objDoc.parseError.errorCode, -1)
        Return -1
    EndIf
    ;Tom Hohmann 2008/02/29
    Return 1
EndFunc   ;==>_XMLLoadXML

; #FUNCTION# ===================================================================
; Name ..........: _XMLCreateFile
; Description ...: Create a new blank metafile with header.
; Syntax.........:  _XMLCreateFile($strPath, $strRoot[, $fOverwrite = False[, $fUTF8 = False[, $ver = -1]]])
; Parameters ....: $strPath       - The xml filename with full path to create
;                  $strRoot       - The root of the xml file to create
;                  $fOverwrite    - boolean flag to auto overwrite existing file of same name.
;                  $fUTF8         - boolean flag to specify UTF-8 encoding in header.
;                  $iVer          - specifically try to use the version supplied here.
; Return values .: Success        - 1
;                  Failure        - -1 and sets @Error to:
;                  |0 - No error
;                  |1 - Failed to create file
;                  |2 - No object
;                  |3 - File creation failed MSXML error
;                  |4 - File exists
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLCreateFile($strPath, $strRoot, $fOverwrite = False, $fUTF8 = False, $ver = -1)
    Local $retval, $fe, $objPI, $rootElement
    $fe = FileExists($strPath)
    If $fe And Not $fOverwrite 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
            _XMLError("Error failed to create file: " & $strPath & @CRLF & "File exists.")
            SetError(4)
            Return -1
        EndIf
    Else
        FileCopy($strPath, $strPath & ".old", 1)
        FileDelete($strPath)
        $fe = False
    EndIf
    If $fe = False Then
        If $ver <> -1 Then
            If $ver > -1 And $ver < 7 Then
                $objDoc = ObjCreate("Msxml2.DOMDocument." & $ver & ".0")
                If IsObj($objDoc) Then
                    $DOMVERSION = $ver
                EndIf
            Else
                MsgBox(266288, "Error:", "Failed to create object with MSXML version " & $ver)
                SetError(3)
                Return 0
            EndIf
        Else
            For $x = 8 To 0 Step -1
                If FileExists(@SystemDir & "\msxml" & $x & ".dll") Then
                    $objDoc = ObjCreate("Msxml2.DOMDocument." & $x & ".0")
                    If IsObj($objDoc) Then
                        $DOMVERSION = $x
                        ExitLoop
                    EndIf
                EndIf
            Next
        EndIf
        If Not IsObj($objDoc) Then
            Return SetError(2)
        EndIf
        If $fUTF8 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
        $objDoc.save($strPath)
        ;_XMLSaveDoc (,1)

        If $objDoc.parseError.errorCode <> 0 Then
            _XMLError("Error Creating specified file: " & $strPath)
            ;           Tom Hohmann 2008/02/29
            SetError(1, $objDoc.parseError.errorCode, -1)
            Return -1
        EndIf
        Return 1
    Else
        _XMLError("Error! Failed to create file: " & $strPath)
        SetError(1)
        Return 0
    EndIf
    Return 1
EndFunc   ;==>_XMLCreateFile

; #FUNCTION# ===================================================================
; Name ..........: _XMLSelectNodes
; Description ...: Selects XML Node(s) based on XPath input from root node.
; Syntax.........:  _XMLSelectNodes($strXPath)
; Parameters ....: $strXPath      - xml tree path from root node (root/child/child..)
; Return values .: Success        - An array of Nodes(count is in first element)
;                  Failure        - -1 and set @Error = 1
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLSelectNodes($strXPath)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLSelectNodes")
        Return SetError(2, 0, -1)
    EndIf
    Local $objNode, $objNodeList, $arrResponse[1], $xmlerr
    $objNodeList = $objDoc.selectNodes($strXPath)
    If Not IsObj($objNodeList) Then
        _XMLError("\nNo matching nodes found")
        Return SetError(1, 0, -1)
    EndIf
    If $objNodeList.length < 1 Then
        _XMLError("\nNo matching nodes found")
        Return SetError(1, 0, -1)
    EndIf
    For $objNode In $objNodeList
        _XMLArrayAdd($arrResponse, $objNode.nodeName)
        _DebugWrite($objNode.nodeName)
        _DebugWrite($objNode.namespaceURI)
    Next
    $arrResponse[0] = $objNodeList.length
    Return $arrResponse
    _XMLError("Error Selecting Node(s): " & $strXPath & $xmlerr)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLSelectNodes

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetField
; Description ...: Get XML Field(s) based on XPath input from root node.
; Syntax.........:  _XMLGetField($strXPath)
; Parameters ....: $strXPath      - The XML tree path from root node (root/child/child..)
; Return values .: Success        - An array of fields text values(count is in first element)
;                  Failure        - -1 and sets @Error = 1
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetField($strXPath)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetField")
        Return SetError(1, 2, -1)
    EndIf
    Local $objNodeList, $arrResponse[1], $xmlerr, $szNodePath
    $objNodeList = $objDoc.selectSingleNode($strXPath)
    If Not IsObj($objNodeList) Then
        _XMLError("\nNo Matching Nodes found")
        $arrResponse[0] = 0
        Return SetError(2, 0, -1)
    EndIf
    If $objNodeList.hasChildNodes() Then
        Local $count = $objNodeList.childNodes.length
        For $x = 1 To $count
            $objChild = $objNodeList.childNodes($x)
            _DebugWrite("ParentNode=" & $objNodeList.parentNode.nodeType)
            If $objNodeList.parentNode.nodeType = $NODE_DOCUMENT Then
                $szNodePath = "/" & $objNodeList.baseName & "/*[" & $x & "]"
            Else
                $szNodePath = $objNodeList.baseName & "/*[" & $x & "]"
            EndIf

            $aRet = _XMLGetValue($szNodePath)
            If IsArray($aRet) Then
                If UBound($aRet) > 1 Then
                    _XMLArrayAdd($arrResponse, $aRet[1])
                    _DebugWrite("GetField>Text:" & $aRet[1])
                EndIf
            Else
                _XMLArrayAdd($arrResponse, "")
                _DebugWrite("GetField>Text:" & "")
            EndIf
        Next
        $arrResponse[0] = UBound($arrResponse) - 1
        Return $arrResponse
    Else
        $arrResponse[0] = 0
        _XMLError("\nNo Child Nodes found")
        Return SetError(1, 0, -1)
    EndIf
    _XMLError("Error Selecting Node(s): " & $strXPath & $xmlerr)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLGetField

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetValue
; Description ...: Get XML values based on XPath input from root node.
; Syntax.........:  _XMLGetValue($strXPath)
; Parameters ....: $strXPath      - xml tree path from root node (root/child/child..)
; Return values .: Success        - An array of fields text values(count is in first element)
;                  Failure        - -1 and sets @Error = 1, @Extended to:
;                  |0 - No matching node.
;                  |1 - No object passed.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetValue($strXPath)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetValue")
        Return SetError(1, 1, -1)
    EndIf
    Local $objNodeList, $arrResponse[1], $objNodeChild, $xmlerr
    _DebugWrite("GetValue>$strXPath:" & $strXPath)
    $objNodeList = $objDoc.documentElement.selectNodes($strXPath)
    If $objNodeList.length > 0 Then
        _DebugWrite("GetValue list length:" & $objNodeList.length)
        For $objNode In $objNodeList
            If $objNode.hasChildNodes() = False Then
                _XMLArrayAdd($arrResponse, $objNode.nodeValue)
            Else
                For $objNodeChild In $objNode.childNodes()
                    If $objNodeChild.nodeType = $NODE_CDATA_SECTION Then
                        _XMLArrayAdd($arrResponse, $objNodeChild.data)
                        _DebugWrite("GetValue>CData:" & $objNodeChild.data)
                    ElseIf $objNodeChild.nodeType = $NODE_TEXT Then
                        _XMLArrayAdd($arrResponse, $objNodeChild.Text)
                        _DebugWrite("GetValue>Text:" & $objNodeChild.Text)
                    EndIf
                Next
            EndIf
        Next
        $arrResponse[0] = UBound($arrResponse) - 1
        Return $arrResponse
    Else
        $xmlerr = @CRLF & "No matching node(s)found!"
        Return SetError(1, 0, -1)
    EndIf
    _XMLError("Error Retrieving: " & $strXPath & $xmlerr)

    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLGetValue

; #FUNCTION# ===================================================================
; Name ..........: _XMLDeleteNode
; Description ...: Deletes XML Node based on XPath input from root node.
; Syntax.........:  _XMLDeleteNode($strXPath)
; Parameters ....: $strXPath      - The XML tree path from root node (root/child/child..)
; Return values .: Success        - 1
;                  Failure        - -1 and sets @Error to:
;                  |0 - No error
;                  |1 - Deletion error
;                  |2 - No object passed
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLDeleteNode($strXPath)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLDeleteNode")
        Return SetError(2, 0, -1)
    EndIf
    Local $objNode, $xmlerr
    $objNode = $objDoc.selectNodes($strXPath)
    If Not IsObj($objNode) Then $xmlerr = @CRLF & "Node Not found"
    If @error = 0 Then
        For $objChild In $objNode
            If $objChild.hasChildNodes Then
                For $objGrandChild in $objChild.childNodes
                    If $objGrandChild.nodeType = $NODE_TEXT Then
                        If StringStripWS($objGrandChild.text,7) = "" Then
                            $objChild.removeChild($objGrandChild)
                        EndIf
                    EndIf
                Next
            EndIf
            $objChild.parentNode.removeChild($objChild)
        Next
        _XMLSaveDoc($strFile)
        Return 1
    EndIf
    _XMLError("Error Deleting Node: " & $strXPath & $xmlerr)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLDeleteNode

; #FUNCTION# ===================================================================
; Name ..........: _XMLDeleteAttr
; Description ...: Delete XML Attribute based on XPath input from root node.
; Syntax.........:  _XMLDeleteAttr($strXPath, $strAttrib)
; Parameters ....: $strXPath      - The XML tree path from root node (root/child/child..)
;                  $strAttribute  - The attribute node to delete
; Return values .: Success        - 1
;                  Failure        - -1 and sets @Error to:
;                  |0 - No error
;                  |1 - Error removing attribute
;                  |2 - No object
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLDeleteAttr($strXPath, $strAttrib)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLDeleteAttr")
        Return SetError(2, 0, -1)
    EndIf
    Local $objNode, $objAttr, $xmlerr
    $objNode = $objDoc.selectSingleNode($strXPath)
    If IsObj($objNode) Then
        $objAttr = $objNode.getAttributeNode($strAttrib)
        If Not (IsObj($objAttr)) Then
            _XMLError("Attribute " & $strAttrib & " does not exist!")
            Return SetError(2, 0, -1)
        EndIf
        $objAttr = $objNode.removeAttribute($strAttrib)
        _XMLSaveDoc($strFile)
        Return 1
    EndIf
    _XMLError("Error Removing Attribute: " & $strXPath & " - " & $strAttrib & @CRLF & $xmlerr)
    $xmlerr = ""
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLDeleteAttr

; #FUNCTION# ===================================================================
; Name ..........: _XMLDeleteAttrNode
; Description ...: Delete XML Attribute node based on XPath input from root node.
; Syntax.........:  _XMLDeleteAttrNode($strXPath, $strAttrib)
; Parameters ....: $strXpath      - XML tree path from root node (root/child/child..)
;                  $strAttrib     - The attribute node to delete
; Return values .: Success        - 1
;                  Failure        - -1 and sets @Error to:
;                  |0 - No error
;                  |1 - Error removing node
;                  |2 - No object
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLDeleteAttrNode($strXPath, $strAttrib)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLDeleteAttrNode")
        Return SetError(2, 0, -1)
    EndIf
    Local $objNode, $objAttr, $xmlerr
    $objNode = $objDoc.selectSingleNode($strXPath)
    If Not IsObj($objNode) Then
        _XMLError("\nSpecified node not found!")
        Return SetError(2, 0, -1)
    EndIf
    $objAttr = $objNode.removeAttributeNode($objNode.getAttributeNode($strAttrib))
    _XMLSaveDoc($strFile)
    If Not (IsObj($objAttr)) Then
        _XMLError("\nUnspecified error:!")
        Return SetError(1, 0, -1)
    EndIf
    Return 1
EndFunc   ;==>_XMLDeleteAttrNode

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetAttrib
; Description ...: Get XML Field based on XPath input from root node.
; Syntax.........:  _XMLGetAttrib($strXPath, $strAttrib[, $strQuery = ""])
; Parameters ....: $strXPath      - XML tree path from root node (root/child/child..)
;                  $strAttrib     - The attribute node to read.
;                  $strQuery      - The query string in xml format
; Return values .: Success        - The attribute value.
;                  Failure        - -1 and sets @Error to:
;                  |0 - No error
;                  |1 - Attribute not found.
;                  |2 - No object
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetAttrib($strXPath, $strAttrib, $strQuery = "")
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetAttrib")
        Return SetError(2, 0, -1)
    EndIf
    ;Local $objNodeList, $arrResponse[1], $i, $xmlerr, $objAttr
    Local $objNodeList, $arrResponse, $i, $xmlerr, $objAttr
    $objNodeList = $objDoc.documentElement.selectNodes($strXPath & $strQuery)
    _DebugWrite("Get Attrib length= " & $objNodeList.length)
    If $objNodeList.length > 0 Then
        For $i = 0 To $objNodeList.length - 1
            $objAttr = $objNodeList.item($i).getAttribute($strAttrib)
            $arrResponse = $objAttr
            _DebugWrite("RET>>" & $objAttr)
        Next
        Return $arrResponse
    EndIf
    $xmlerr = "\nNo qualified items found"
    _XMLError("Attribute " & $strAttrib & " not found for: " & $strXPath & $xmlerr)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLGetAttrib

; #FUNCTION# ===================================================================
; Name ..........: _XMLSetAttrib
; Description ...: Set XML Field(s) based on XPath input from root node.
; Syntax.........:  _XMLSetAttrib($strXPath, $strAttrib[, $strValue = ""[, $iIndex =-1]])
; Parameters ....: $strXPath      - Xml tree path from root node (root/child/child..)
;                  $strAttrib     - The attribute to set.
;                  $strValue      - The value to give the attribute defaults to ""
;                  $iIndex        - Used to specify a specific index for "same named" nodes.
; Return values .: Success        - Anarray of fields text values
;                  Failure        - -1 and sets @error to 1
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLSetAttrib($strXPath, $strAttrib, $strValue = "", $iIndex = -1)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLSetAttrib")
        Return SetError(1, 8, -1)
    EndIf
    Local $objNodeList, $arrResponse[1], $i
    $objNodeList = $objDoc.selectNodes($strXPath)
    _DebugWrite(" Node list Length: " & $objNodeList.length)
    If @error = 0 And $objNodeList.length > 0 Then
        If $iIndex > 0 Then
            $arrResponse[0] = $objNodeList.item($iIndex).SetAttribute($strAttrib, $strValue)
        Else
            ReDim $arrResponse[$objNodeList.length]
            For $i = 0 To $objNodeList.length - 1
                $arrResponse[$i] = $objNodeList.item($i).SetAttribute($strAttrib, $strValue)
                If $objDoc.parseError.errorCode <> 0 Then ExitLoop
            Next
        EndIf
        If $objDoc.parseError.errorCode <> 0 Then
            _XMLError("Error setting attribute for: " & $strXPath & @CRLF & $objDoc.parseError.reason)
            Return SetError(1, $objDoc.parseError.errorCode, -1)
        EndIf
        _XMLSaveDoc($strFile)
        Return $arrResponse
    EndIf
    _XMLError("Error failed to set attribute for: " & $strXPath & @CRLF)
    SetError(1)
    Return -1
EndFunc   ;==>_XMLSetAttrib

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetAllAttrib
; Description ...: Get all XML Field(s) attributes based on XPath input from root node.
; Syntax.........:  _XMLGetAllAttrib($strXPath, ByRef $aName, ByRef $aValue[, $strQry = ""])
; Parameters ....: $strXPath      - XML tree path from root node (root/child/child..)
;                  $aName         - The array to return the attrib names
;                  $aValue        - The array to return the attrib values
;                  $strQuery      - DOM compliant query string (not really necessary as it becomes part of the path)
; Return values .: Success        - array of fields text values(number of items is in [0][0])
;                  Failure        - @error set to 1 and returns -1
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetAllAttrib($strXPath, ByRef $aName, ByRef $aValue, $strQry = "")
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetAllAttrib")
        Return SetError(1, 9, -1)
    EndIf
    Local $objNodeList, $objQueryNodes, $objNode, $arrResponse[2][1], $i
    $objQueryNodes = $objDoc.selectNodes($strXPath & $strQry)
    If $objQueryNodes.length > 0 Then
        For $objNode In $objQueryNodes
            $objNodeList = $objNode.attributes
            If ($objNodeList.length) Then
                _DebugWrite("Get all attrib " & $objNodeList.length)
                ReDim $arrResponse[2][$objNodeList.length + 2]
                ReDim $aName[$objNodeList.length]
                ReDim $aValue[$objNodeList.length]
                For $i = 0 To $objNodeList.length - 1
                    $arrResponse[0][$i + 1] = $objNodeList.item($i).nodeName
                    $arrResponse[1][$i + 1] = $objNodeList.item($i).Value
                    $aName[$i] = $objNodeList.item($i).nodeName
                    $aValue[$i] = $objNodeList.item($i).Value
                Next
            Else
                _XMLError("No Attributes found for node")
                Return SetError(1, 0, -1)
            EndIf
        Next
        $arrResponse[0][0] = $objNodeList.length
        Return $arrResponse
    EndIf
    _XMLError("Error retrieving attributes for: " & $strXPath & @CRLF)
    Return SetError(1, 0, -1)
    ;   EndIf
EndFunc   ;==>_XMLGetAllAttrib

; #FUNCTION# ===================================================================
; Name ..........: _XMLUpdateField
; Description ...: Update existing node(s) based on XPath specs.
; Syntax.........:  _XMLUpdateField($strXPath, $strData)
; Parameters ....: $strXPath      - Path from root node.
;                  $strData       - The data to update the node with.
; Return values .: Success        - 1
;                  Failure        - -1 and sets @error to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLUpdateField($strXPath, $strData)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLUpdateField")
        Return SetError(1, 9, -1)
    EndIf
    Local $objField, $fUpdate, $objNode
    #forceref $objField
    $objField = $objDoc.selectSingleNode($strXPath)
    If IsObj($objField) Then
        If $objField.hasChildNodes Then
            For $objChild In $objField.childNodes()
                If $objChild.nodetype = $NODE_TEXT Then
                    $objChild.Text = $strData
                    $fUpdate = True
                    ExitLoop
                EndIf
            Next
        EndIf
        If $fUpdate = False Then
            $objNode = $objDoc.createTextNode($strData)
            $objField.appendChild($objNode)
        EndIf
        _XMLSaveDoc($strFile)
        $objField = ""
        Return 1
    EndIf
    _XMLError("Failed to update field for: " & $strXPath & @CRLF)
    Return SetError(1, 0, -1)

EndFunc   ;==>_XMLUpdateField

; #FUNCTION# ===================================================================
; Name ..........: _XMLCreateCDATA
; Description ...: Create a CDATA SECTION node directly under root.
; Syntax.........:  _XMLCreateCDATA($strNode, $strCDATA[, $strNameSpc = ""])
; Parameters ....: $strNode       - name of node to create
;                  $strData       - CDATA value
;                  $strNameSpc    - the namespace to specifiy if the xml uses one.
; Return values .: Success        - 1
;                  Failure        - 1 and sets @Error to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......: fixme, won't append to exisiting node. must create new node.
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLCreateCDATA($strNode, $strCDATA, $strNameSpc = "")
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLCreateCDATA")
        Return SetError(1, 10, -1)
    EndIf
    Local $objChild, $objNode
    $objNode = $objDoc.createNode($NODE_ELEMENT, $strNode, $strNameSpc)
    If IsObj($objNode) Then
        If Not ($objNode.hasChildNodes()) Then
            _AddFormat($objDoc, $objNode)
        EndIf
        $objChild = $objDoc.createCDATASection($strCDATA)
        $objNode.appendChild($objChild)
        $objDoc.documentElement.appendChild($objNode)
        _XMLSaveDoc($strFile)
        _AddFormat($objDoc)
        $objChild = ""
        Return 1
    EndIf
    _XMLError("Failed to create CDATA Section: " & $strNode & @CRLF)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLCreateCDATA

; #FUNCTION# ===================================================================
; Name ..........: _XMLCreateComment
; Description ...: Create a COMMENT node at specified path.
; Syntax.........:  _XMLCreateComment($strNode, $strComment)
; Parameters ....: $strNode       - The name of node to create.
;                  $strComment    - The comment to add the to the xml file.
; Return values .: Success        - 1
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLCreateComment($strNode, $strComment)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLCreateComment")
        Return SetError(1, 11, -1)
    EndIf
    Local $objChild, $objNode

    $objNode = $objDoc.selectSingleNode($strNode)
    If IsObj($objNode) Then
        If Not ($objNode.hasChildNodes()) Then
            _AddFormat($objDoc, $objNode)
        EndIf
        $objChild = $objDoc.createComment($strComment)
        $objNode.insertBefore($objChild, $objNode.childNodes(0))
        _XMLSaveDoc($strFile)
        _AddFormat($objDoc)
        $objChild = ""
        Return 1
    EndIf
    _XMLError("Failed to root child: " & $strNode & @CRLF)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLCreateComment

; #FUNCTION# ===================================================================
; Name ..........: _XMLCreateAttribute
; Description ...: Adds an XML Attribute to specified node.
; Syntax.........:  _XMLCreateAttrib($strXPath, $strAttrName[, $strAttrValue = ""])
; Parameters ....: $strXPath      - The XML tree path from root node (root/child/child..)
;                  $strAttrName   - The attribute to set.
;                  $strAttrValue  - The value to give the attribute, defaults to "".
; Return values .: Success        - 1
;                  Failure        - 0 or @error set to 0 and return -1
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLCreateAttrib($strXPath, $strAttrName, $strAttrValue = "")
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLCreateAttrib")
        Return SetError(1, 12, -1)
    EndIf
    Local $objNode, $objAttr, $objAttrVal, $err
    $objNode = $objDoc.selectSingleNode($strXPath)
    If IsObj($objNode) Then
        $objAttr = $objDoc.createAttribute($strAttrName);, $strNameSpc)
        $objNode.SetAttribute($strAttrName, $strAttrValue)
        _XMLSaveDoc($strFile)
        $objAttr = 0
        $objAttrVal = 0
        $objNode = 0
        $err = $objDoc.parseError.errorCode
        If $err = 0 Then Return 1
    EndIf
    _XMLError("Error creating Attribute: " & $strAttrName & @CRLF & $strXPath & " does not exist." & @CRLF)
    Return 0
EndFunc   ;==>_XMLCreateAttrib

; #FUNCTION# ===================================================================
; Name ..........: _XMLCreateRootChild
; Description ...: Create node directly under root.
; Syntax.........:  _XMLCreateRootChild($strNode[, $strData = ""[, $strNameSpc = ""]])
; Parameters ....: $strNode       - The name of node to create.
;                  $strData       - The optional value to create
;                  $$strNameSpc   - the namespace to specifiy if the file uses one.
; Return values .: Success        - 1
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLCreateRootChild($strNode, $strData = "", $strNameSpc = "")
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLCreateRootChild")
        Return SetError(1, 14, -1)
    EndIf
    ;ConsoleWrite("_XMLCreateRootChild:"&$strNode&@LF)
    Local $objChild
    If Not ($objDoc.documentElement.hasChildNodes()) Then
        _AddFormat($objDoc)
    EndIf
    $objChild = $objDoc.createNode($NODE_ELEMENT, $strNode, $strNameSpc)
    If IsObj($objChild) Then
        If $strData <> "" Then $objChild.text = $strData
        $objDoc.documentElement.appendChild($objChild)
        _XMLSaveDoc($strFile)
        _AddFormat($objDoc)
        $objChild = 0
        Return 1
    EndIf
    _XMLError("Failed to root child: " & $strNode & @CRLF)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLCreateRootChild

; #FUNCTION# ===================================================================
; Name ..........: _XMLCreateRootNodeWAttr
; Description ...: Create a child node under root node with attributes.
; Syntax.........:  _XMLCreateRootNodeWAttr($strNode, $aAttr, $aVal[, $strData = ""[, $strNameSpc = ""]])
; Parameters ....: $strNode       - The node to add with attibute(s)
;                  $aAttr         - The attribute name(s) -- can be array
;                  $aVal          - The attribute value(s) -- can be array
;                  $strData       - The optional value to give the node.
; Return values .: Success        - 1
;                  Failure        - -1 and @error set to:
;                  |1 - Could not create node.
;                  |2 - Mismatch between attribute name and value counts.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......: This function requires that each attribute name has  a corresponding value.
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLCreateRootNodeWAttr($strNode, $aAttr, $aVal, $strData = "", $strNameSpc = "")
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLCreateRootNodeWAttr")
        Return SetError(1, 15, -1)
    EndIf
    Local $objChild, $objAttr, $objAttrVal
    $objChild = $objDoc.createNode($NODE_ELEMENT, $strNode, $strNameSpc)
    If IsObj($objChild) Then
        If $strData <> "" Then $objChild.text = $strData
        If Not ($objDoc.documentElement.hasChildNodes()) Then
            _AddFormat($objDoc)
        EndIf
        If IsArray($aAttr) And IsArray($aVal) Then
            If UBound($aAttr) <> UBound($aVal) Then
                _XMLError("Attribute and value mismatch" & @CRLF & "Please make sure each attribute has a matching value.")
                Return SetError(2, 15, -1)
            Else
                Local $i
                For $i = 0 To UBound($aAttr) - 1
                    If $aAttr[$i] = "" Then
                        _XMLError("Error creating child node: " & $strNode & @CRLF & " Attribute Name Cannot be NULL." & @CRLF)
                        Return SetError(1, 0, -1)
                    EndIf
                    $objAttr = $objDoc.createAttribute($aAttr[$i]);, $strNameSpc)
                    $objChild.SetAttribute($aAttr[$i], $aVal[$i])
                Next
            EndIf
        Else
            $objAttr = $objDoc.createAttribute($aAttr)
            $objChild.SetAttribute($aAttr, $aVal)
        EndIf
        $objDoc.documentElement.appendChild($objChild)
        _XMLSaveDoc($strFile)
        _AddFormat($objDoc)
        $objChild = 0
        Return 1
    EndIf
    _XMLError("Failed to create root child with attributes: " & $strNode & @CRLF)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLCreateRootNodeWAttr

; #FUNCTION# ===================================================================
; Name ..........: _XMLCreateChildNode
; Description ...: Create a child node under the specified XPath Node.
; Syntax.........:  _XMLCreateChildNode($strXPath, $strNode[, $strData = ""[, $strNameSpc = ""]])
; Parameters ....: $strXPath      - The node from root.
;                  $strNode       - Node name to add.
;                  $strData       - Value to give the node
; Return values .: Success        - 1
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLCreateChildNode($strXPath, $strNode, $strData = "", $strNameSpc = "")
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLCreateChildNode")
        Return SetError(1, 16, -1)
    EndIf
    Local $objParent, $objChild, $objNodeList
    $objNodeList = $objDoc.selectNodes($strXPath)
    If IsObj($objNodeList) And $objNodeList.length > 0 Then
        For $objParent In $objNodeList
            If Not ($objParent.hasChildNodes()) Then
                _AddFormat($objDoc, $objParent)
            EndIf
            If $strNameSpc = "" Then
                If Not ($objParent.namespaceURI = 0 Or $objParent.namespaceURI = "") Then $strNameSpc = $objParent.namespaceURI
            EndIf
            ;ConsoleWrite("$strNameSpc=" & $strNameSpc & @LF)
            $objChild = $objDoc.createNode($NODE_ELEMENT, $strNode, $strNameSpc)
            If $strData <> "" Then $objChild.text = $strData
            $objParent.appendChild($objChild)
            _AddFormat($objDoc, $objParent)
        Next
        _XMLSaveDoc($strFile)
        $objParent = ""
        $objChild = ""
        Return 1
    EndIf
    _XMLError("Error creating child node: " & $strNode & @CRLF & $strXPath & " does not exist." & @CRLF)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLCreateChildNode

; #FUNCTION# ===================================================================
; Name ..........: _XMLCreateChildWAttr
; Description ...: Create a child node(s) under the specified XPath Node with attributes.
; Syntax.........:  _XMLCreateChildWAttr($strXPath, $strNode, $aAttr, $aVal[, $strData = ""[, $strNameSpc = ""]])
; Parameters ....: $sPath         - Path from root
;                  $sNode         - The node to add with attibute(s)
;                  $aAttr         - The attribute name(s) -- can be array
;                  $aVal          - The attribute value(s) -- can be array
;                  $strData       - The optional value to give the child node.
; Return values .: Success        - 1
;                  Failure        - -1, @error set to:
;                  |1 - Could not create node.
;                  |2 - Mismatch between attribute name and value counts.
;                  |3 - Attribute Name cannot be empty string.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......: This function requires that each attribute name has  a corresponding value.
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLCreateChildWAttr($strXPath, $strNode, $aAttr, $aVal, $strData = "", $strNameSpc = "")
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLCreateChildWAttr")
        Return SetError(1, 18, -1)
    EndIf
    Local $objParent, $objChild, $objAttr, $objAttrVal, $objNodeList
    $objNodeList = $objDoc.selectNodes($strXPath)
    _DebugWrite("Node Selected")
    If IsObj($objNodeList) And $objNodeList.length <> 0 Then
        _DebugWrite("Entering if")
        For $objParent In $objNodeList
            If Not ($objParent.hasChildNodes()) Then
                _AddFormat($objDoc, $objParent)
            EndIf
            _DebugWrite("Entering for")
            If $strNameSpc = "" Then
                If Not ($objParent.namespaceURI = 0 Or $objParent.namespaceURI = "") Then $strNameSpc = $objParent.namespaceURI
            EndIf
            $objChild = $objDoc.createNode($NODE_ELEMENT, $strNode, $strNameSpc)
            If @error Then Return -1
            If $strData <> "" Then $objChild.text = $strData
            If IsArray($aAttr) And IsArray($aVal) Then
                If UBound($aAttr) <> UBound($aVal) Then
                    _XMLError("Attribute and value mismatch" & @CRLF & "Please make sure each attribute has a matching value.")
                    Return SetError(2, 0, -1)
                Else
                    Local $i
                    For $i = 0 To UBound($aAttr) - 1
                        _DebugWrite("Entering inside for")
                        If $aAttr[$i] = "" Then
                            _XMLError("Error creating child node: " & $strNode & @CRLF & " Attribute Name Cannot be NULL." & @CRLF)
                            Return SetError(1, 0, -1)
                        EndIf
                        _DebugWrite($aAttr[$i] & " " & $strNameSpc)
                        $objAttr = $objDoc.createAttribute($aAttr[$i]);, $strNameSpc)
                        If @error Then ExitLoop
                        $objChild.SetAttribute($aAttr[$i], $aVal[$i])
                        If @error <> 0 Then
                            _XMLError("Error creating child node: " & $strNode & @CRLF & $strXPath & " does not exist." & @CRLF)
                            Return SetError(1, 0, -1)
                        EndIf
                        _DebugWrite("Looping inside for")
                    Next
                EndIf
            Else
                If IsArray($aAttr) Or IsArray($aVal) Then
                    _XMLError("Type non-Array and Array detected" & @LF)
                    Return SetError(1, 0, -1)
                EndIf
                If $aAttr = "" Then
                    _XMLError("Attribute Name cannot be empty string." & @LF)
                    Return SetError(3, 0, -1)
                EndIf
                _DebugWrite($aAttr & " " & $strNameSpc)
                $objAttr = $objDoc.createAttribute($aAttr);, $strNameSpc)
                $objChild.SetAttribute($aAttr, $aVal)
            EndIf
            $objParent.appendChild($objChild)
            _DebugWrite("Looping for")
        Next
        _AddFormat($objDoc, $objParent)
        _XMLSaveDoc($strFile)
        _DebugWrite("Saved")
        $objParent = ""
        $objChild = ""
        _DebugWrite("Returning")
        Return 1
    EndIf
    _XMLError("Error creating child node: " & $strNode & @CRLF & $strXPath & " does not exist." & @CRLF)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLCreateChildWAttr

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetChildText
; Description ...: Selects XML child Node(s) of an element based on XPath input from root node.
; Syntax.........:  _XMLGetChildText($strXPath)
; Parameters ....: $strXPath      - The xml tree path from root node (root/child/child..)
; Return values .: Success        - An array of Nodes.
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetChildText($strXPath)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetChildText")
        Return SetError(1, 19, -1)
    EndIf
    Local $objNodeList, $arrResponse[1], $xmlerr
    $objNodeList = $objDoc.selectSingleNode($strXPath)
    If Not IsObj($objNodeList) Then
        _XMLError(@CRLF & "No Matching Nodes found")
        $arrResponse[0] = 0
        Return SetError(1, 0, -1)
    EndIf
    If $objNodeList.hasChildNodes() Then
        For $objChild In $objNodeList.childNodes()
            If $objChild.nodeType = $NODE_ELEMENT Then
                _XMLArrayAdd($arrResponse, $objChild.baseName)
            ElseIf $objChild.nodeType = $NODE_TEXT Then
                _XMLArrayAdd($arrResponse, $objChild.text)
            EndIf
        Next
        $arrResponse[0] = UBound($arrResponse) - 1
        Return $arrResponse
    EndIf
    $arrResponse[0] = 0
    $xmlerr = @CRLF & "No Child Text Nodes found"
    _XMLError("Error Selecting Node(s): " & $strXPath & $xmlerr)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLGetChildText

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetChildNodes
; Description ...: Selects XML child Node(s) of an element based on XPath input from root node.
; Syntax.........:  _XMLGetChildNodes($strXPath)
; Parameters ....: $strXPath      - The xml tree path from root node (root/child/child..)
; Return values .: Success        - An array of Nodes, count in [0] element.
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetChildNodes($strXPath)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetChildNodes")
        Return SetError(1, 20, -1)
    EndIf
    Local $objNodeList, $arrResponse[1], $xmlerr
    $objNodeList = $objDoc.selectSingleNode($strXPath)
    If Not IsObj($objNodeList) Then
        _XMLError(@LF & "No Matching Nodes found")
        $arrResponse[0] = 0
        Return SetError(1, 0, -1)
    EndIf
    If $objNodeList.hasChildNodes() Then
        For $objChild In $objNodeList.childNodes()
            If $objChild.nodeType() = $NODE_ELEMENT Then
                _DebugWrite($objChild.NamespaceURI & "::" & $objChild.baseName & @LF)
                _XMLArrayAdd($arrResponse, $objChild.baseName)
            EndIf
        Next
        $arrResponse[0] = UBound($arrResponse) - 1
        Return $arrResponse
    EndIf
    $arrResponse[0] = 0
    $xmlerr = @LF & "No Child Nodes found"
    _XMLError("Error Selecting Node(s): " & $strXPath & $xmlerr)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLGetChildNodes

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetChildren
; Description ...: Selects XML child Node(s) of an element based on XPath input from root node and returns there text values.
; Syntax.........:  _XMLGetChildren($strXPath)
; Parameters ....: $strXPath      - The XML tree path from root node (root/child/child..)
; Return values .: Success        - An array where:
;                  |$array[0][0] = Size of array
;                  |$array[1][0] = Name
;                  |$array[1][1] = Text
;                  |$array[1][2] = NameSpaceURI
;                  |...
;                  |$array[n][0] = Name
;                  |$array[n][1] = Text
;                  |$array[n][2] = NamespaceURI
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetChildren($strXPath)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetChildren")
        Return SetError(1, 21, -1)
    EndIf
    Local $objNodeList, $arrResponse[1][3], $xmlerr
    $objNodeList = $objDoc.selectSingleNode($strXPath)
    If Not IsObj($objNodeList) Then
        _XMLError(@LF & "No Matching Nodes found")
        $arrResponse[0][0] = 0
        Return SetError(1, 0, -1)
    EndIf
    If $objNodeList.hasChildNodes() Then
        For $objChild In $objNodeList.childNodes()
            If $objChild.nodeType() = $NODE_ElEMENT Then
                If $objChild.hasChildNodes() Then
                    For $objChildNode in $objChild.childNodes()
                        If $objChildNode.nodeType() =  $NODE_TEXT Then
                            Local $dims = UBound($arrResponse, 1)
                            ReDim $arrResponse[$dims + 1][3]
                            $arrResponse[$dims][0] = $objChildNode.parentNode.baseName
                            $arrResponse[$dims][1] = $objChildNode.text
                            $arrResponse[$dims][2] = $objChildNode.NamespaceURI
                            ;_XMLArrayAdd($arrResponse, $objChild.baseName)
                        EndIf
                    Next
                EndIf
            EndIf
        Next
        $arrResponse[0][0] = UBound($arrResponse, 1) - 1
        Return $arrResponse
    EndIf
    $arrResponse[0][0] = 0
    $xmlerr = @LF & "No Child Nodes found"
    _XMLError("Error Selecting Node(s): " & $strXPath & $xmlerr)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLGetChildren

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetNodeCount
; Description ...: Get Node Count based on XPath input from root node.
; Syntax.........:  _XMLGetNodeCount($strXPath[, $strQry = ""[, $iNodeType = 1]])
; Parameters ....: $strXPath      - The XML tree path from root node (root/child/child..
;                  $strQry        - A DOM compliant query string (not really necessary as it becomes part of the path
;                  $iNodeType     - The type of node to count. (element, attrib, comment etc.)
; Return values .: Success        - Number of nodes found (can be 0)
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com> & DickB
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetNodeCount($strXPath, $strQry = "", $iNodeType = 1)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetNodeCount")
        Return SetError(1, 22, -1)
    EndIf
    Local $objQueryNodes, $objNode, $nodeCount = 0, $errMsg
    $objQueryNodes = $objDoc.selectNodes($strXPath & $strQry)
    If @error = 0 And $objQueryNodes.length > 0 Then
        For $objNode In $objQueryNodes
            If $objNode.nodeType = $iNodeType Then $nodeCount = $nodeCount + 1
        Next
        Return $nodeCount
    Else
        $errMsg = "No nodes of specified type found."
    EndIf
    _XMLError("Error retrieving node count for: " & $strXPath & @CRLF & $errMsg & @CRLF)
    SetError(1)
    Return -1
    ; EndIf
EndFunc   ;==>_XMLGetNodeCount

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetAllAttribIndex
; Description ...: Get all XML Field(s) attributes based on Xpath and specific index.
; Syntax.........:  _XMLGetAllAttribIndex($strXPath, ByRef $aName, ByRef $aValue[, $strQry = ""[, $iNodeIndex = 0]])
; Parameters ....: $strXpath      - The xml tree path from root node (root/child/child..)
;                  $aNames        - The array to return the attrib names in.
;                  $aValue        - The array to return the attrib values in.
;                  $strQry        - DOM compliant query string (not really necessary as it becomes
;                  $iNodeIndex    - The index of node to retrieve.
; Return values .: Success        - The number of elements.
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetAllAttribIndex($strXPath, ByRef $aName, ByRef $aValue, $strQry = "", $iNodeIndex = 0)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetAllAttribIndex")
        Return SetError(1, 23, -1)
    EndIf
    Local $objNodeList, $objQueryNodes, $i ;, $arrResponse[2][1]
    $objQueryNodes = $objDoc.selectNodes($strXPath & $strQry)
    If $objQueryNodes.length > 0 Then
        $objNodeList = $objQueryNodes.item($iNodeIndex).attributes
        _DebugWrite("GetAllAttribIndex " & $objNodeList.length)
        ;ReDim $arrResponse[2][$objNodeList.length + 1]
        ReDim $aName[$objNodeList.length]
        ReDim $aValue[$objNodeList.length]
        For $i = 0 To $objNodeList.length - 1
            ;$arrResponse[0][$i] = $objNodeList.item ($i).nodeName
            ;$arrResponse[1][$i] = $objNodeList.item ($i).Value
            $aName[$i] = $objNodeList.item($i).nodeName
            $aValue[$i] = $objNodeList.item($i).Value
        Next
        ;Return $arrResponse
        Return $objNodeList.length
    EndIf
    _XMLError("Error retrieving attributes for: " & $strXPath & @CRLF)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLGetAllAttribIndex

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetPath
; Description ...: Return a nodes full path based on XPath input from root node.
; Syntax.........:  _XMLGetPath($strXPath)
; Parameters ....: $strXPath      - The XML tree path from root node (root/child/child..)
; Return values .: Success        - An array of node names from root, count in [0] element.
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetPath($strXPath)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetPath")
        Return SetError(1, 24, -1)
    EndIf
    If $DOMVERSION < 4 Then
        _XMLError("Error DOM Version: " & "MSXML Version 4 or greater required for this function")
        Return SetError(1, 0, -1)
    EndIf
    Local $objNodeList, $arrResponse[1], $objNodeChild, $xmlerr, $nodepath, $ns
    $objNodeList = $objDoc.selectNodes($strXPath)
    If $objNodeList.length > 0 Then
        _DebugWrite("GetPath list length:" & $objNodeList.length)
        For $objNode In $objNodeList
            Local $objNode1 = $objNode
            $nodepath = ""
            $nodepathtag = ""
            If $objNode.nodeType <> $NODE_DOCUMENT Then
                $ns = $objNode.namespaceURI()
                If $ns <> "" Then
                    $ns = StringRight($ns, StringLen($ns) - StringInStr($ns, "/", 0, -1)) & ":"
                EndIf
                If $ns = 0 Then $ns = ""
                $nodepath = "/" & $ns & $objNode.nodeName() & $nodepath
            EndIf
            Do
                $objParent = $objNode1.parentNode()
                _DebugWrite("parent " & $objParent.nodeName() & @LF)
                If $objParent.nodeType <> $NODE_DOCUMENT Then
                    $ns = $objParent.namespaceURI()
                    If $ns <> "" Then
                        ;$ns = StringRight($ns, StringLen($ns) - StringInStr($ns, "/", 0, -1)) & ":"
                        $ns &= ":"
                    EndIf
                    If $ns = 0 Then $ns = ""
                    $nodepath = "/" & $ns & $objParent.nodeName() & $nodepath
                    $objNode1 = $objParent
                Else
                    $objNode1 = 0
                EndIf
                $objParent = 0
            Until (Not (IsObj($objNode1)))
            _DebugWrite("Path node> " & $nodepath & @LF)
            _XMLArrayAdd($arrResponse, $nodepath)
        Next
        $arrResponse[0] = UBound($arrResponse) - 1
        Return $arrResponse
    EndIf
    $xmlerr = @CRLF & "No matching node(s)found!"
    _XMLError("Error Retrieving: " & $strXPath & $xmlerr)
    Return SetError(1, 0, -1)
EndFunc   ;==>_XMLGetPath

; #FUNCTION# ===================================================================
; Function Name  :  _XMLGetPathInternal
; Description ...: Returns the path of a valid node object.
; Syntax ........:  _XMLGetPathInternal($objNode)
; Parameters ....: $objNode       - A valid node object
; Return values .: Success        - Path from root as string.
;                  Failure        - An empty string and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats at netmdc.com/>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetPathInternal($objNode)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLGetPathInternal")
        Return SetError(1, 25, "")
    EndIf
    Local $nodepath, $na, $objParent
    If IsObj($objNode) Then
        $nodepath = "/" & $objNode.baseName
        Do
            $objParent = $objNode.parentNode()
            _DebugWrite("parent" & $objParent.nodeName() & ">" & @LF)
            If $objParent.nodeType <> $NODE_DOCUMENT Then
                $ns = $objParent.namespaceURI()
                If $ns = 0 Then $ns = ""
                If $ns <> "" Then
                    $ns = StringRight($ns, StringLen($ns) - StringInStr($ns, "/", 0, -1)) & ":"
                EndIf
                $nodepath = "/" & $ns & $objParent.nodeName() & $nodepath
                $objNode = $objParent
            Else
                $objNode = 0
            EndIf
            $objParent = 0
        Until (Not (IsObj($objNode)))
        _DebugWrite("Path node>" & $nodepath & @LF)
        Return ($nodepath)
    Else
        Return SetError(1, 0, "")
    EndIf
EndFunc   ;==>_XMLGetPathInternal

; #FUNCTION# ===================================================================
; Name ..........: _XMLReplaceChild
; Description ...: Replaces a node with another
; Syntax.........:  _XMLReplaceChild($objOldNode, $objNewNode[, $ns = ""])
; Parameters ....: $objOldNode    - The node to replace
;                  $objNewNode    - The replacement node.
; Return values .: Success        - 1.
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com> adapted from
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLReplaceChild($objOldNode, $objNewNode, $ns = "")
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLReplaceChild")
        Return SetError(1, 26, -1)
    EndIf
    If $objOldNode = "" Or $objNewNode = "" Then Return SetError(1)
    Local $nodeRoot
    Local $nodeOld
    Local $nodeNew
    Local $nodeTemp
    Local $fSuccess = False
    ;No error handling done
    With $objDoc
        ;;.Load "c:\books.xml"
        $nodeRoot = .documentElement
        $oldNodes = $nodeRoot.selectNodes($objOldNode)
        ;'For each Node
        For $nodeOld In $oldNodes
            ;Create a New element
            $nodeNew = .createNode($NODE_ELEMENT, $objNewNode, $ns)
            ;Copy attributes
            For $nodeTemp In $nodeOld.Attributes
                $nodeNew.Attributes.setNamedItem($nodeTemp.cloneNode(True))
            Next
            ;Copy Child Nodes
            For $nodeTemp In $nodeOld.childNodes
                $nodeNew.appendChild($nodeTemp)
            Next
            ;Replace with the renamed node
            If IsObj($nodeOld.parentNode.replaceChild($nodeNew, $nodeOld)) Then $fSuccess = 1
            If Not ($objDoc.parseError.errorCode = 0) Then
                _XMLError("_XMLReplaceChild:" & @LF & "Error Replacing Child: " & _
                        $objDoc.parseError.errorCode & _
                        " " & $objDoc.parseError.reason)
                $fSuccess = False
                ExitLoop
            Else
                $fSuccess = True
            EndIf
        Next
        .save($strFile)
    EndWith
    $nodeRoot = 0
    $nodeOld = 0
    $nodeNew = 0
    $nodeTemp = 0
    If ($fSuccess = False) Then Return SetError(1, 0, -1)
    Return 1
EndFunc   ;==>_XMLReplaceChild

; #FUNCTION# ===================================================================
; Name ..........: _XMLSchemaValidate
; Description ...: Validates a document against a dtd.
; Syntax.........:  _XMLSchemaValidate($sXMLFile, $strNameSpc, $sXSDFile)
; Parameters ....: $sXMLFile      - The file to validate
;                  $strNameSpc    - xml namespace
;                  $sXSDFile      - DTD file to validate against.
; Return values .: Success        - 1
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLSchemaValidate($sXMLFile, $strNameSpc, $sXSDFile)
    Local $cache, $xmldoc
    $cache = ObjCreate("Msxml2.XMLSchemaCache." & $DOMVERSION & ".0")
    If Not IsObj($cache) Then
        MsgBox(266288, "XML Error", "Unable to instantiate the XML object" & @LF & "Please check your components.")
        Return SetError(1, 0, -1)
    EndIf
    $cache.add($strNameSpc, $sXSDFile)
    $xmldoc = ObjCreate("Msxml2.DOMDocument." & $DOMVERSION & ".0")
    If Not IsObj($xmldoc) Then
        MsgBox(266288, "XML Error", "Unable to instantiate the XML object" & @LF & "Please check your components.")
        Return SetError(1, 0, -1)
    EndIf
    $xmldoc.async = False
    $xmldoc.schemas = $cache
    $xmldoc.load($sXMLFile)
    If Not ($xmldoc.parseError.errorCode = 0) Then
        _XMLError("_XMLSchemaValidate:" & @LF & "Error: " & $xmldoc.parseError.errorCode & " " & $xmldoc.parseError.reason)
        Return SetError($xmldoc.parseError.errorCode)
    EndIf
    Return 1
EndFunc   ;==>_XMLSchemaValidate

; #FUNCTION# ===================================================================
; Name ..........: _XMLGetDomVersion
; Description ...: Returns the version of msxml that is in use for the document.
; Syntax.........:  _XMLGetDomVersion()
; Parameters ....:                none
; Return values .: Success        - msxml version
;                  Failure        - 0
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLGetDomVersion()
    Return $DOMVERSION
EndFunc   ;==>_XMLGetDomVersion

; #FUNCTION# ===================================================================
; Name ..........: _XMLError
; Description ...: Sets or Gets error message that may be generated by the UDF functs.
; Syntax.........:  _XMLError($sError = "")
; Parameters ....: $sError        - Error message to set.
; Return values .: Success        - one of the following:
;                  |$sError <> "" - Nothing.
;                  |$sError = "" - Last error set.
;                  Failure        - Nothing.
; Author ........: Stephen Podhajecki <gehossafats@netmdc.com>
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLError($sError = "")
    If $sError = "" Then
        $sError = $sXML_error
        $sXML_error = ""
        Return $sError
    Else
        $sXML_error = StringFormat($sError)
    EndIf
    _DebugWrite($sXML_error)
EndFunc   ;==>_XMLError

; #FUNCTION# ===================================================================
; Name ..........: _XMLCOMEerr
; Description ...: Displays a message box with the COM Error.
; Syntax.........:  _XMLCOMEerr()
; Parameters ....:                None
; Return values .:
; Author ........: SvenP 's error handler
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLCOMEerr()
    _ComErrorHandler()
    Return
EndFunc   ;==>_XMLCOMEerr

; #FUNCTION# ===================================================================
; Name ..........: _ComErrorHandler
; Description ...: A COM error handling routine.
; Syntax.........: _ComErrorHandler($quiet = "")
; Parameters ....: $quiet - Work silently
; Return values .: None
; Author ........:
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _ComErrorHandler($quiet = "")
    Local $COMErr_Silent, $HexNumber
    ; ==============================================================================
    ;added silent switch to allow the func returned to the option to display custom
    ;error messages
    If $quiet = True Or $quiet = False Then
        $COMErr_Silent = $quiet
        $quiet = ""
    EndIf
    ; ==============================================================================
    $HexNumber = Hex($oXMLMyError.number, 8)
    If @error Then Return
    Local $msg = "COM Error with DOM!" & @CRLF & @CRLF & _
            "err.description is: " & @TAB & $oXMLMyError.description & @CRLF & _
            "err.windescription:" & @TAB & $oXMLMyError.windescription & @CRLF & _
            "err.number is: " & @TAB & $HexNumber & @CRLF & _
            "err.lastdllerror is: " & @TAB & $oXMLMyError.lastdllerror & @CRLF & _
            "err.scriptline is: " & @TAB & $oXMLMyError.scriptline & @CRLF & _
            "err.source is: " & @TAB & $oXMLMyError.source & @CRLF & _
            "err.helpfile is: " & @TAB & $oXMLMyError.helpfile & @CRLF & _
            "err.helpcontext is: " & @TAB & $oXMLMyError.helpcontext
    If $COMErr_Silent <> True Then
        MsgBox(0, @AutoItExe, $msg)
    Else
        _XMLError($msg)
    EndIf
    SetError(1)
EndFunc   ;==>_ComErrorHandler

; #FUNCTION# ===================================================================
; Name ..........: _DebugWrite
; Description ...: Writes a message to console with a crlf on the end
; Syntax.........:  _DebugWrite($strMsg[, $sLineEnding = @LF])
; Parameters ....: $strMsg        - The message to display
;                  $sLineEnding   - Line ending to add
; Return values .: On Succes      - None.
;                  Failure        - None.
; Author ........:
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _DebugWrite($strMsg, $sLineEnding = @LF)
    If $fDEBUGGING Then
        ConsoleWrite(StringFormat($strMsg) & $sLineEnding)
    EndIf
EndFunc   ;==>_DebugWrite

; #FUNCTION# ===================================================================
; Name ..........: _SetDebug
; Description ...: Turn debugging info on or off
; Syntax.........:  _SetDebug($fDbug = True)
; Parameters ....: $fDbug         - Boolean value for debugging.
; Return values .: Success        - The debugging state.
; Author ........:
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _SetDebug($fDbug = True)
    $fDEBUGGING = $fDbug
    _DebugWrite("Debug = " & $fDEBUGGING)
    Return $fDEBUGGING
EndFunc   ;==>_SetDebug

; #FUNCTION# ===================================================================
; Name ..........: _XMLUDFVersion
; Description ...: Returns UDF version number
; Syntax.........:  _XMLUDFVersion()
; Parameters ....:                None
; Return values .: Success        - The UDF version number
; Author ........: Stephen Podhajecki
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLUDFVersion()
    Return $_XMLUDFVER
EndFunc   ;==>_XMLUDFVersion

; #FUNCTION# ===================================================================
; Name ..........: _XMLTransform
; Description ...:
; Syntax.........:  _XMLTransform([$oXMLDoc = ""[, $Style = ""[, $szNewDoc = ""]]])
; Parameters ....: $oXMLDoc       - The document to transform
;                  $Style         - The stylesheet to use
;                  $szNewDoc      - Save to this file.
; Return values .: Success        - Returns True
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats at netmdc dot com>, Modified by WeaponX
; Modified ......:
; Remarks .......: Default stylesheet is used for indenting.
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLTransform($oXMLDoc = "", $Style = "", $szNewDoc = "")
    If $oXMLDoc = "" Then
        $oXMLDoc = $objDoc
    EndIf
    If Not IsObj($oXMLDoc) Then
        _XMLError("No object passed to function _XMLTransform")
        Return SetError(1, 29, -1)
    EndIf
    Local $fIndented = False
    Local $xslt = ObjCreate("MSXML2.XSLTemplate." & $DOMVERSION & ".0")
    Local $xslDoc = ObjCreate("MSXML2.FreeThreadedDOMDocument." & $DOMVERSION & ".0")
    Local $xmldoc = ObjCreate("MSXML2.DOMDocument." & $DOMVERSION & ".0")
    Local $xslProc
    $xslDoc.async = False
    If FileExists($Style) Then
        _DebugWrite("LoadXML:1:" & $xslDoc.load($Style) & @LF)
    Else
        _DebugWrite("LoadXML2:" & $xslDoc.loadXML(_GetDefaultStyleSheet()) & @LF)
    EndIf
    If $xslDoc.parseError.errorCode <> 0 Then
        _XMLError("Error Transforming NodeToObject: " & $xslDoc.parseError.reason)
    EndIf

    $xslt.stylesheet = $xslDoc
    $xslProc = $xslt.createProcessor()
    $xslProc.input = $objDoc
    $oXMLDoc.transformNodeToObject($xslDoc, $xmldoc)
    If $oXMLDoc.parseError.errorCode <> 0 Then
        _XMLError("_XMLTransform:" & @LF & "Error Transforming NodeToObject: " & $oXMLDoc.parseError.reason)
        $fIndented = False
    Else
        $fIndented = True
    EndIf
    If $fIndented Then
        ;Write transformed xml to a file if a filename is given
        If $szNewDoc <> "" Then
            $xmldoc.save($szNewDoc)
            If $xmldoc.parseError.errorCode <> 0 Then
                _XMLError("_XMLTransform:" & @LF & "Error Saving: " & $xmldoc.parseError.reason)
                $fIndented = False
            EndIf
        Else
            ;Overwrite original object with transformed object
            $objDoc = $xmldoc
            _XMLSaveDoc($strFile)
            If $oXMLDoc.parseError.errorCode <> 0 Then
                _XMLError("_XMLTransform:" & @LF & "Error Saving: " & $oXMLDoc.parseError.reason)
                $fIndented = False
            EndIf
        EndIf
    EndIf
    $xslProc = 0
    $xslt = 0
    $xslDoc = 0
    $xmldoc = 0
    If $fIndented = False Then Return SetError(1, 0, -1)
    Return $fIndented
EndFunc   ;==>_XMLTransform

; #INTERNAL_USE_ONLY#==========================================================
; Name ..........: _GetDefaultStyleSheet
; Description ...: Internal function, returns the default indenting style sheet.
; Syntax.........:  _GetDefaultStyleSheet()
; Parameters ....:
; Return values .: Success        - The default stylesheet.
;                  Failure        - Nothing.
; Author ........: Hew Wolff - Art & Logic, Inc.
; Modified ......:
; Remarks .......: Posted all over the web.
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _GetDefaultStyleSheet()

    Return '<?xml version="1.0" encoding="UTF-8"?>' & _
            '<!--' & _
            'Converts XML into a nice readable format.' & _
            'Tested with Saxon 6.5.3.' & _
            'As a test, this stylesheet should not change when run on itself.' & _
            'But note that there are no guarantees about attribute order within an' & _
            'element (see http://www.w3.org/TR/xpath#dt-document-order), or about' & _
            'which characters are escaped (see' & _
            'http://www.w3.org/TR/xslt#disable-output-escaping).' & _
            'I did not test processing instructions, CDATA sections, or' & _
            'namespaces.' & _
            'Hew Wolff' & _
            'Senior Engineer' & _
            'Art & Logic, Inc.' & _
            'www.artlogic.com' & _
            '-->' & _
            '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">' & _
            '<!-- Take control of the whitespace. -->' & _
            '<xsl:output method="xml" indent="no" encoding="UTF-8"/>' & _
            '<xsl:strip-space elements="*"/>' & _
            '<xsl:preserve-space elements="xsl:text"/>' & _
            '<!-- Copy comments, and elements recursively. -->' & _
            '<xsl:template match="*|comment()">' & _
            '<xsl:param name="depth">0</xsl:param>' & _
            '<!--' & _
            'Set off from the element above if one of the two has children.' & _
            'Also, set off a comment from an element.' & _
            'And set off from the XML declaration if necessary.' & _
            '-->' & _
            '<xsl:variable name="isFirstNode" select="count(../..) = 0 and position() = 1"/>' & _
            '<xsl:variable name="previous" select="preceding-sibling::node()[1]"/>' & _
            '<xsl:variable name="adjacentComplexElement" select="count($previous/*) &gt; 0 or count(*) &gt; 0"/>' & _
            '<xsl:variable name="adjacentDifferentType" select="not(($previous/self::comment() and self::comment()) or ($previous/self::* and self::*))"/>' & _
            '<xsl:if test="$isFirstNode or ($previous and ($adjacentComplexElement or $adjacentDifferentType))">' & _
            '<xsl:text>&#xA;</xsl:text>' & _
            '</xsl:if>' & _
            '<!-- Start a new line.' & _
            '<xsl:text>&#xA;</xsl:text> -->' & _
            '<xsl:call-template name="indent">' & _
            '<xsl:with-param name="depth" select="$depth"/>' & _
            '</xsl:call-template>' & _
            '<xsl:copy>' & _
            '<xsl:if test="self::*">' & _
            '<xsl:copy-of select="@*"/>' & _
            '<xsl:apply-templates>' & _
            '<xsl:with-param name="depth" select="$depth + 1"/>' & _
            '</xsl:apply-templates>' & _
            '<xsl:if test="count(*) &gt; 0">' & _
            '<xsl:text>&#xA;</xsl:text>' & _
            '<xsl:call-template name="indent">' & _
            '<xsl:with-param name="depth" select="$depth"/>' & _
            '</xsl:call-template>' & _
            '</xsl:if>' & _
            '</xsl:if>' & _
            '</xsl:copy>' & _
            '<xsl:variable name="isLastNode" select="count(../..) = 0 and position() = last()"/>' & _
            '<xsl:if test="$isLastNode">' & _
            '<xsl:text>&#xA;</xsl:text>' & _
            '</xsl:if>' & _
            '</xsl:template>' & _
            '<xsl:template name="indent">' & _
            '<xsl:param name="depth"/>' & _
            '<xsl:if test="$depth &gt; 0">' & _
            '<xsl:text>   </xsl:text>' & _
            '<xsl:call-template name="indent">' & _
            '<xsl:with-param name="depth" select="$depth - 1"/>' & _
            '</xsl:call-template>' & _
            '</xsl:if>' & _
            '</xsl:template>' & _
            '<!-- Escape newlines within text nodes, for readability. -->' & _
            '<xsl:template match="text()">' & _
            '<xsl:call-template name="escapeNewlines">' & _
            '<xsl:with-param name="text">' & _
            '<xsl:value-of select="."/>' & _
            '</xsl:with-param>' & _
            '</xsl:call-template>' & _
            '</xsl:template>' & _
            '<xsl:template name="escapeNewlines">' & _
            '<xsl:param name="text"/>' & _
            '<xsl:if test="string-length($text) &gt; 0">' & _
            '<xsl:choose>' & _
            '<xsl:when test="substring($text, 1, 1) = ' & "'#xA;'" & '">' & _
            '<xsl:text disable-output-escaping="yes">&amp;#xA;</xsl:text>' & _
            '</xsl:when>' & _
            '<xsl:otherwise>' & _
            '<xsl:value-of select="substring($text, 1, 1)"/>' & _
            '</xsl:otherwise>' & _
            '</xsl:choose>' & _
            '<xsl:call-template name="escapeNewlines">' & _
            '<xsl:with-param name="text" select="substring($text, 2)"/>' & _
            '</xsl:call-template>' & _
            '</xsl:if>' & _
            '</xsl:template>' & _
            '</xsl:stylesheet>'
EndFunc   ;==>_GetDefaultStyleSheet

; #INTERNAL_USE_ONLY#==========================================================
; Name ..........: _AddFormat
; Description ...:
; Syntax.........:  _AddFormat($objDoc[, $objParent = ""])
; Parameters ....: $objDoc         - Document to format
;                  $objParent     - Optional node to add formatting to
; Return values .: Success        - 1
;                  Failure        - -1 and @error set to 1.
; Author ........: Stephen Podhajecki <gehossafats a t netmdc.com>
; Modified ......:
; Remarks .......: Just break up the tags, no indenting is done here.
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _AddFormat($objDoc, $objParent = "")
    If $fADDFORMATTING = True Then
        If Not IsObj($objDoc) Then
            _XMLError("No object passed to function _XMLAddFormat")
            Return SetError(1, 30, -1)
        EndIf
        Local $objFormat = $objDoc.createTextNode(@CR)
        If IsObj($objParent) Then
            $objParent.appendChild($objFormat)
        Else
            $objDoc.documentElement.appendChild($objFormat)
        EndIf
        _XMLSaveDoc($strFile)
    EndIf
    Return 1
EndFunc   ;==>_AddFormat

; #FUNCTION# ===================================================================
; Name ..........: _XMLSetAutoSave
; Description ...: Set the automatic save to on or off
; Syntax.........:  _XMLSetAutoSave($fSave = True)
; Parameters ....: $fSave         - Boolean value to set automatic saving.
; Return values .: Success        - Previous state of autosave.
; Author ........: Stephen Podhajecki <gehossafats a t netmdc.com>
; Modified ......:
; Remarks .......: Defaults to true.
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLSetAutoSave($fSave = True)
    Local $oldSave = $fXMLAUTOSAVE
    $fXMLAUTOSAVE = $fSave
    Return $oldSave
EndFunc   ;==>_XMLSetAutoSave

; #FUNCTION# ===================================================================
; Name ..........: _XMLSetAutoFormat
; Description ...: Turn auto formatting on or off
; Syntax.........:  _XMLSetAutoFormat($fAutoFormat = True)
; Parameters ....: $fAutoFormat   - Boolean flag for automatic formatting
; Return values .: Success        - The previous state.
;                  Failure        - Nothing.
; Author ........: Stephen Podhajecki {gehossafats at netmdc. com}
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLSetAutoFormat($fAutoFormat = True)
    Local $oldFormat = $fADDFORMATTING
    $fADDFORMATTING = $fAutoFormat
    Return $oldFormat
EndFunc   ;==>_XMLSetAutoFormat

; #FUNCTION# ===================================================================
; Name ..........: _XMLSaveDoc
; Description ...: Save the current xml doc
; Syntax.........:  _XMLSaveDoc([$sFile=""[,$iForce = 0]])
; Parameters ....: $sFile         - The filename to save the xml doc as.
;                  $iForce        - If true, save the file regardless of autosave state.
; Return values .: Success        - 1
;                  Failure        - -1 and @error set to the following:
;                  |1 - error trying to save.
;                  |2 - Autosave is off.
;                  |3 - No filename given for save and default is blank.
; Author ........: Stephen Podhajecki {gehossafats at netmdc. com}
; Modified ......:
; Remarks .......: Defaults to the current filename.
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLSaveDoc($sFile = "", $iForce = 0)
    If ($fXMLAUTOSAVE = True) Or ($iForce = 1) Then
        If $sFile = "" Then $sFile = $strFile
        If $sFile <> "" Then
            $objDoc.save($sFile)
            If $objDoc.parseError.errorCode <> 0 Then
                _XMLError("_XMLSaveDoc: Saving " & $sFile & " failed.:" & @LF & _
                        $objDoc.parseError.errorCode & _
                        " " & $objDoc.parseError.reason)
                Return SetError(1, 0, -1)
            EndIf
            Return 1
        Else
            _XMLError("_XMLSaveDoc:" & " Error Saving: No Filename given")
            Return SetError(3, 0, -1)
        EndIf
    EndIf
    Return SetError(2, 0, 1)
EndFunc   ;==>_XMLSaveDoc

; #FUNCTION# ===================================================================
; Name ..........: _XMLNodeExists
; Description ...: Checks for the existence of a node or nodes matching the specified path
; Syntax.........:  _XMLNodeExists($strXPath)
; Parameters ....: $strXPath      - Path to check for.
; Return values .: Success        - 1 or Higher , 0
;                  Failure        - 0 and @Error set to:
;                  |0 - No error.
;                  |1 - No XML object @extended = 31.
;                  |2 - Node not found.
; Author ........: Stephen Podhajecki <gehossafats a t netmdc.com>
; Modified ......:
; Remarks .......: Returns the number of nodes found (could be greater than 1)
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLNodeExists($strXPath)
    If Not IsObj($objDoc) Then
        _XMLError("No object passed to function _XMLNodeExists")
        Return SetError(1, 31, 0)
    EndIf
    Local $objNode, $iCount
    Local $objNode = $objDoc.SelectNodes($strXPath)
    If IsObj($objNode) Then $iCount = $objNode.length
    $objNode = 0
    If $iCount Then Return $iCount
    Return SetError(2, 0, 0)
EndFunc   ;==>_XMLNodeExists

; #INTERNAL_USE_ONLY#==========================================================
; Name ..........: _XMLArrayAdd
; Description ...: Adds an item to an array.
; Syntax.........:  _XMLArrayAdd(ByRef $avArray, $sValue)
; Parameters ....: $avArray       - The array to modify.
;                  $sValue        - The value to add to the array.
; Return values .: Success        - 1 and value added to array.
;                  Failure        - 0 and @error set to 1
; Author ........:
; Modified ......:
; Remarks .......: Local version of _ArrayAdd to remove dependency on Array.au3
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ==============================================================================
Func _XMLArrayAdd(ByRef $avArray, $sValue)
    If IsArray($avArray) Then
        ReDim $avArray[UBound($avArray) + 1]
        $avArray[UBound($avArray) - 1] = $sValue
        SetError(0)
        Return 1
    Else
        SetError(1)
        Return 0
    EndIf
EndFunc   ;==>_XMLArrayAdd

 

EDIT: Removed a script comment related to one of my other projects.

Edited by toasterking

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

  • Similar Content

    • jesus40
      By jesus40
      Hello friends, i have a working curl command that show informations about my account on binance.com, but_it dont work with autoit code without curl.exe.
      I want to do it without curl, because the whole process much Slower_ with StdoutRead (I want get the response in variable.)
      My Curl command in Autoit:
      This 2 are works, but_ i would like to do it without curl.exe
      $apikey="XYZ" sCommand = @ScriptDir & '\curl.exe -k -H "X-MBX-APIKEY: ' & $apikey & '" -X GET "https://api.binance.com/api/v3/account?' & $request the same in .bat  file
      curl.exe -k -H "X-MBX-APIKEY: XYZ" -X GET "https://api.binance.com/api/v3/account?timestamp=1514917812000&signature=85bdee77e53cd521e1d5229fbfb459d53799c42b3fa4596d73f1520fad5f965a" (I use curl with -k option which allows curl to make insecure connections, because there is problem with the sites certificate, (cURL error 60))
       
      I tried many variations, this is the latest... I cant get the same response.
      curl $error message (I changed ): {"code":-2015,"msg":"Invalid API-key, IP, or permissions for action."}
      autoit version $error message (Response code:400): Mandatory parameter 'timestamp' was not sent, was empty/null, or malformed.
       
      $request = $query & '&signature=' & $signature $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("GET", "https://api.binance.com/api/v3/account", False) $oHTTP.SetRequestHeader("X-MBX-APIKEY", $apikey) $oHTTP.Send($request) $oReceived = $oHTTP.ResponseText $oStatusCode = $oHTTP.Status If $oStatusCode <> 200 then MsgBox(4096, "Response code", $oStatusCode) EndIf  
      thanks
    • jandings
      By jandings
      Hello there,
      since I spent some time to access the REST-API of the web shop system Shopware, I'd like to share a few lines to make life easier for others.
      With this you can access your Shopware database, reading and writing all kind of data. 
      Replies are JSON style.
      To work with JSON I usually depend on either just own AutoIt string operations or this AutoIt library:
      ; File        : Json.au3 (2015.01.08)
      ; Purpose    : A Non-Strict JavaScript Object Notation (JSON) Parser UDF
      ; Author    : Ward
      $UserName="xxxx" ;Shopware credentials of Shopware user who has the API checkbox ticked $PassWord="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ;API-Key of this user, NOT the Password $URL="www.XXX.com/api/" $Command="orders/64682?useNumberAsId=true" ;A list of commands and options is available through shopware REST-API help; Here we read order number 64682 $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("GET", "https://" & $URL & $Command , False) $oHTTP.SetCredentials($UserName, $PassWord, 0) $oHTTP.Send() $response = $oHTTP.ResponseText ConsoleWrite ($response & @CRLF & @CRLF)  
    • jandings
      By jandings
      Hello there,
      and one more: how to access the REST-API of the project management system plan.io (which is based on Redmine), I'd like to share a few lines to make life easier for others.
      With this you can access your plan.io data, reading and writing all kind of data. 
      Replies are JSON style (though XML is possible, that's an option)
      To work with JSON I usually depend on either just own AutoIt string operations or this AutoIt library, which I find best 11.2017:
      ; File        : Json.au3 (2015.01.08)
      ; Purpose    : A Non-Strict JavaScript Object Notation (JSON) Parser UDF
      ; Author    : Ward
      $UserName="xxxxxx" ;plan.io credentials (usually e-mail address) $PassWord="xxxx" ;plan.io credentials $APIKey="xxxxxxxxxxxxxxx" ;This is the API Key from PlanIO, you can get it from the frontend, just google or ask plan.io help $URL="xxxx.plan.io/" $Command="issues.json?limit=50" ;A list of commands and options is available through plan.io REST-API help $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("GET", "https://" & $URL & $Command &" X-Redmine-API-Key: " & $APIKey, False) $oHTTP.SetCredentials($UserName, $PassWord, 0) $oHTTP.Send() $response = $oHTTP.ResponseText ConsoleWrite ($response & @CRLF & @CRLF)
    • nznet
      By nznet
      Hi Guys,
      I have been trying to write the API calls to Coinigy.com in AutoitScipt. I have managed to solve most of them put are having trouble with the ones that require parameters to be passed.
      The source to the API calls can be found here:
      http://docs.coinigy.apiary.io/#reference/market-data/market-data/data-{type:history}
      Example code from this site:
      curl --include \      --request POST \      --header "Content-Type: application/json" \      --header "X-API-KEY: " \      --header "X-API-SECRET: " \      --data-binary "    {         \"exchange_code\": \"GDAX\",         \"exchange_market\": \"BTC/USD\",         \"type\": \"history\"     }" \ ' https://api.coinigy.com/api/v1/data '  
      This data one is really annoying me. I have the following so far:
      #include <Array.au3> #include <string.au3> #include <MsgBoxConstants.au3> #Region Coinigy Const Global $sCoinigyAPIUrl = "https://api.coinigy.com/api/v1/" #EndRegion Coinigy Const #Region keys Global Const $sCoinigyAPIKey = "" ; just removed my APIKey Global Const $sCoinigyAPISecret = "" ; just removed my APISecret #EndRegion keys $sResults = CoinigyQueryPrivate("data", "exchange_code=GDAX&exchange_market=BTC/USD&type=history") ; Trade history, asks and bids for any supported exchange/market ConsoleWrite("Market Data: " & $sResults & @CRLF & @CRLF) Func CoinigyQueryPrivate($sMethod, $sParameters)     Local $oHTTP = ObjCreate("winhttp.winhttprequest.5.1")     $oHTTP.Open("POST", $sCoinigyAPIUrl & $sMethod, False)     $oHTTP.SetRequestHeader("X-API-KEY", $sCoinigyAPIKey)     $oHTTP.SetRequestHeader("X-API-SECRET", $sCoinigyAPISecret)    ; $oHTTP.Send(Binary($sParameters)) ; tried this as well     $oHTTP.Send($sParameters)     Local $sReceived = $oHTTP.ResponseText     Return $sReceived EndFunc   ;==>CoinigyQueryPrivate  
      If I do other queries that don't require Parameters they work perfectly. I am just totally stumped by the parameter passing queries. I have tried everything and I still can't get it to go. Would really appreciate some help.
      If you want to try for yourself live, Coinigy.com give a free 30 trial.... 
      Please help...
      Thanks in advance.
    • falcontechnics
      By falcontechnics
      Dear master, hello,
      I got the speech API from Google. But I could not find how to use. Could you help me with a simple example?
      "https://speech.googleapis.com/v1/speech:recognize?key=MyKey"