Jump to content

Recommended Posts

Posted (edited)
1 hour ago, Hiyoal said:

Different length than yours but the object is of the same type??

That means that we are not using the same xml file.  Which leads me to believe that there may be even more differences.  Did you make any changes to any of the files after you unzipped it?

 

*** Update ***

I just downloaded the latest version again and I get a length of 13 also.

Edited by TheXman
Posted (edited)

@Hiyoal

Okay, I think I found the issue.  The difference is my xml.au3.  It appears that I had found an issue with it a while ago and fixed it in my version.  The issue actually was related to Example 6. 

Please try the xml.au3 file that I have attached.  Please let me know if it resolves the issue you are having.  You can do a diff between mine and the one in the latest zip if you want to see the modifications.  There are only 2 changes.  One line was modified and the other line was added.

 

@mLipok

If you need an explanation of my modifications, please let me know.  I would be happy to explain the issue that I found and how the 2 lines fix the issue with Example 6.

 

 

XML.au3

Edited by TheXman
Posted

Champion. 

Thats working now for the example and my own script.

I saw the changes. The addition to validate the object made sense but I didn't understand the removal of the "#text" ContinueLoop in that for loop.

Im stoked I wasn't going bonkers, thanks for the help TheXman.

Posted

 

You're welcome!   :thumbsup:

 

2 minutes ago, Hiyoal said:

I didn't understand the removal of the "#text" ContinueLoop in that for loop.

It has to do with the  data in the _ArrayDisplay().  If you comment out that line, you will see #text entries in the table and you will see several COM errors saying something about trying to assign null objects.  So basically that line just omits any #text properties from being added to the table, which also prevents the COM errors.

Posted

Haha makes sense.

As soon as I wrote my post I started tinkering away with checking nodeNames individually without going through _XML_Array_GetNodesProperties and saw all of those #text entries.

  • 6 months later...
Posted (edited)
On 9/28/2019 at 3:49 AM, TheXman said:

 

You're welcome!   :thumbsup:

 

It has to do with the  data in the _ArrayDisplay().  If you comment out that line, you will see #text entries in the table and you will see several COM errors saying something about trying to assign null objects.  So basically that line just omits any #text properties from being added to the table, which also prevents the COM errors.

Hi TheXman,

I'm having a strange issue while using "_XML_CreateDOMDocument","_XML_Load" "_XML_SaveToFile" .

While opening Windows SIM "unattend.xml" files using your "XML.au3" UDF (By the way great work by picking up "eltorro" code and adding extra features)

I'm having some issues:

Using "_XML_CreateDOMDocument" and setting up as "Default" (in my case it ends up being "6") I get the following output (upon Load and SaveToFile😞

 

<?xml version="1.0" encoding="utf-8"?><unattend xmlns="urn:schemas-microsoft-com:unattend">

 

Thus missing a "CRLF" at the first entry.

 

I have to change the parameter to "3" to get the proper result (equal to the original file):


Like this:

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">

 

I Just wanted to know if this is normal and related to "__XML_MiscProperty_DomVersion" function, or not.

Because I can keep the "3" to produce the same result. And in fact this is only a glitch (they are both valid to the best of my knowledge) .

 

Nonetheless I do have another more serious issue. Apparently Microsoft is creating special XML's when using WSIM for "SynchronousCommand wcm:action" :

For their own parsing code they require the both " and ' to be represented by &quot; and &apos;  , just to differentiate from their own XML code. 

                <SynchronousCommand wcm:action="add">
                    <Order>1</Order>
                    <Description>Never Expires</Description>
                    <CommandLine>cmd /C WMIC USERACCOUNT WHERE &quot;Name=&apos;TESTUSER&apos;&quot; SET PasswordExpires=FALSE</CommandLine>
                    <RequiresUserInput>false</RequiresUserInput>
                </SynchronousCommand>

 

Unfortunately while using the functions  "_XML_Load" and then "_XML_SaveToFile" all data containing ([&quot;] and [&apos;]) get back to (" and '), resulting in:

 

                <SynchronousCommand wcm:action="add">
                    <Order>1</Order>
                    <Description>Never Expires</Description>
                    <CommandLine>cmd /C WMIC USERACCOUNT WHERE "Name='TESTUSER'" SET PasswordExpires=FALSE</CommandLine>
                    <RequiresUserInput>false</RequiresUserInput>
                </SynchronousCommand>

 

I know this is "kind" of normal, but is there any way to avoid this? I mean keeping the original Raw data? 

 

Thanks in advance,

Regards.

 

 

 

Edited by fjorger
Posted
4 hours ago, fjorger said:

Hi TheXman,

. . .

While opening Windows SIM "unattend.xml" files using your "XML.au3" UDF (By the way great work by picking up "eltorro" code and adding extra features)

As you can see in the 1st post of this topic, this is @mLipok's UDF.  I am just an experienced user of it.  :)

Posted
25 minutes ago, TheXman said:

As you can see in the 1st post of this topic, this is @mLipok's UDF.  I am just an experienced user of it.  :)

Hi TheXman,

Thanks for pointing that out (very silly mistake)😞

@mLipok: My sincere apologies 🤕 (and thanks for your valued work👍).

About the  " and ' to be represented by &quot; and &apos;  while using WSIM, well I discovered that works regardless ;) (using both formats), so no problem whatsoever.

So now I'm just curious about the missing ( "CRLF" at the first entry.) when using "6" instead of "3", could this be a "glitch" in the parsing code, or work as intended?

Best Regards,

FJorgeR.

 

Posted (edited)

Can you attach the shortest script and xml file that reproduces the issue?

Update:

@fjorger

You can disregard the request for a script and test file.  I was able to recreate the issue on my workstation.  When preserving white space, I'm clueless as to why there's a difference between msxml3.dll and msxml6.dll, but there is.  :think:  As you've pointed out, the old version seems to work correctly,

Although this is purely speculation on my part, when releasing msxml6.dll, maybe there was a decision to only preserve white space starting from the XML's root element, not any white space that may occur between the XML prolog and the root element.  No matter how much white space is between the XML prolog and the root xml element, when preserve white space property is true, it is all stripped when using msxml6.dll.

Even this:

<?xml version="1.0" encoding="UTF-8"?>



<SETTINGS>


</SETTINGS>

Becomes this, when using msxml6, with the PreserveWhiteSpace property set to true:

<?xml version="1.0" encoding="UTF-8"?><SETTINGS>


</SETTINGS>

 

Edited by TheXman
Posted (edited)

@fjorger

If you want to ensure that the XML prolog is on its own line (regardless of the MSXML version), then you can TIDY the XML and write the file using a non-XML write function:

#include <xml.au3>

example()

Func example()
    Const $XML_DATA  = _
                       '<?xml version="1.0" encoding="UTF-8"?>' & @CRLF & _
                       @CRLF & _
                       @CRLF & _
                       @CRLF & _
                       '<SETTINGS>' & @CRLF & _
                       @CRLF & _
                       @CRLF & _
                       '</SETTINGS>'

    Local $oXmlDoc
    Local $sXML

    $oXmlDoc = _XML_CreateDOMDocument()     ;Create xml object
    _XML_LoadXML($oXmlDoc, $XML_DATA)       ;Load XML
    $sXML = _XML_Tidy($oXmlDoc, "UTF-8")    ;Tidy XML
    ConsoleWrite($sXML & @CRLF)             ;Display XML
    FileWrite("test.xml", $sXML)            ;Write XML
EndFunc

Output & content of test.xml file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SETTINGS>


</SETTINGS>

 

Edited by TheXman
Posted
15 hours ago, TheXman said:

Can you attach the shortest script and xml file that reproduces the issue?

Update:

@fjorger

You can disregard the request for a script and test file.  I was able to recreate the issue on my workstation.  When preserving white space, I'm clueless as to why there's a difference between msxml3.dll and msxml6.dll, but there is.  :think:  As you've pointed out, the old version seems to work correctly,

Although this is purely speculation on my part, when releasing msxml6.dll, maybe there was a decision to only preserve white space starting from the XML's root element, not any white space that may occur between the XML prolog and the root element.  No matter how much white space is between the XML prolog and the root xml element, when preserve white space property is true, it is all stripped when using msxml6.dll.

Even this:


<?xml version="1.0" encoding="UTF-8"?>



<SETTINGS>


</SETTINGS>

Becomes this, when using msxml6, with the PreserveWhiteSpace property set to true:


<?xml version="1.0" encoding="UTF-8"?><SETTINGS>


</SETTINGS>

 

Hi TheXman,

Apologies for the late reply. 

Thanks for the investigation,  you nailed it.

The mystery is now solved ;)

Posted
2 minutes ago, fjorger said:

Thanks for the investigation,  you nailed it.

The mystery is now solved 

You're welcome!  Glad I could help.  :thumbsup:

Posted
4 hours ago, TheXman said:

@fjorger

If you want to ensure that the XML prolog is on its own line (regardless of the MSXML version), then you can TIDY the XML and write the file using a non-XML write function:

#include <xml.au3>

example()

Func example()
    Const $XML_DATA  = _
                       '<?xml version="1.0" encoding="UTF-8"?>' & @CRLF & _
                       @CRLF & _
                       @CRLF & _
                       @CRLF & _
                       '<SETTINGS>' & @CRLF & _
                       @CRLF & _
                       @CRLF & _
                       '</SETTINGS>'

    Local $oXmlDoc
    Local $sXML

    $oXmlDoc = _XML_CreateDOMDocument()     ;Create xml object
    _XML_LoadXML($oXmlDoc, $XML_DATA)       ;Load XML
    $sXML = _XML_Tidy($oXmlDoc, "UTF-8")    ;Tidy XML
    ConsoleWrite($sXML & @CRLF)             ;Display XML
    FileWrite("test.xml", $sXML)            ;Write XML
EndFunc

Output & content of test.xml file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SETTINGS>


</SETTINGS>

 

Hi again, 

Thank you very much for the function example,  but because I'm loading data from an existing xml file (_XML_Load) then I'm just changing some data (ComputerName) and dumping the data to the same file.

So I would only need the following (first line only): 

Func example()     Const $XML_DATA  = _                        '<?xml version="1.0" encoding="UTF-8"?>' & @CRLF

 

Then I would had to strip the existing (first line). But no worries, I will just force (version 3).

Thanks again for your time and help (appreciated) 

 

  • 3 months later...
Posted (edited)

The function _XML_UpdateField does not work, if an element has no text (I'm using the latest version 1.1.1.13 of the UDF).

This code works:

#include "XML.au3"

Local $sXml = _
    "<root>" & _
        "<child>sometext</child>" & _
    "</root>"

Local $oXmlDoc = _XML_CreateDOMDocument()
_XML_LoadXML($oXmlDoc, $sXml)
_XML_UpdateField($oXmlDoc, "//child", "test")
If @error Then ConsoleWrite("_XML_UpdateField: @error = " & @error & @CRLF)

But when following code is used (only the text of the element "child" has been removed) the function _XML_UpdateField results in @error = 1:

#include "XML.au3"

Local $sXml = _
    "<root>" & _
        "<child></child>" & _
    "</root>"

Local $oXmlDoc = _XML_CreateDOMDocument()
_XML_LoadXML($oXmlDoc, $sXml)
_XML_UpdateField($oXmlDoc, "//child", "test")
If @error Then ConsoleWrite("_XML_UpdateField: @error = " & @error & @CRLF)

 

Edited by DonChunior
Added version information.
Posted (edited)

  

On 7/22/2020 at 8:34 AM, DonChunior said:

The function _XML_UpdateField does not work, if an element has no text

I'm not sure if it was written that way for a reason or whether it is just a small oversight.  However, it only takes a small modification to make it work even if the specified element does not have a text node. 

If you replace the existing function with the one below, it should work either with or without an existing text node.  I tried to make the smallest modification possible in order for it to work.  Keep in mind that this is not my UDF and I do not maintain it.  Therefore, the modified function may or may not get included in any future version.

Func _XML_UpdateField(ByRef $oXmlDoc, $sXPath, $sData) ; Modified by TheXman to create a text node if one does not already exist
    ; Error handler, automatic cleanup at end of function
    Local $oXML_COM_ErrorHandler = ObjEvent("AutoIt.Error", __XML_ComErrorHandler_InternalFunction)
    #forceref $oXML_COM_ErrorHandler

    Local $bUpdateStatus  = False
    Local $oNode_Selected = _XML_SelectSingleNode($oXmlDoc, $sXPath)
    If @error Then
        Return SetError(@error, @extended, $XML_RET_FAILURE)
    ElseIf $oNode_Selected.hasChildNodes Then
        For $oNode_enum_Child In $oNode_Selected.childNodes()
            If $oNode_enum_Child.nodetype = $XML_NODE_TEXT Then
                $oNode_enum_Child.Text = $sData
                $bUpdateStatus = True
                ExitLoop
            EndIf
        Next
    EndIf

    If Not $bUpdateStatus Then
        Local $oNode_Created = $oXmlDoc.createTextNode($sData)
        $oNode_Selected.appendChild($oNode_Created)
        If @error Then Return SetError($XML_ERR_NODEAPPEND, @error, $XML_RET_FAILURE)
    EndIf

    Return SetError($XML_ERR_SUCCESS, $XML_EXT_DEFAULT, $XML_RET_SUCCESS)
EndFunc   ;==>_XML_UpdateField

 

Edited by TheXman
Posted (edited)
16 hours ago, TheXman said:

I'm not sure if it was written that way for a reason or whether it is just a small oversight.  However, it only takes a small modification to make it work even if the specified element does not have a text node.

I think it's a bug in the UDF.
If it were not, then the following code should also result in a error, but it does not:

#include "XML.au3"

Local $sXml = _
    "<root>" & _
        "<child>sometext</child>" & _
    "</root>"

Local $oXmlDoc = _XML_CreateDOMDocument()
_XML_LoadXML($oXmlDoc, $sXml)
_XML_UpdateField($oXmlDoc, "//child", "")
If @error Then ConsoleWrite("_XML_UpdateField: @error = " & @error & @CRLF)
_XML_UpdateField($oXmlDoc, "//child", "test")
If @error Then ConsoleWrite("_XML_UpdateField: @error = " & @error & @CRLF)

Since the last, most current version of the UDF is from March 2017, I don't have much hope that there will be a bugfix.

Nevertheless, thank you very much for your efforts!
I will try out the function you customized!

Edited by DonChunior
  • 1 month later...
Posted
57 minutes ago, DonChunior said:

 ill you look at ....

here you are, waiting for your results

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

  • 2 weeks later...
Posted (edited)
On 9/24/2020 at 5:11 AM, DonChunior said:

@mLipok, will you look at the problem I reported on 22-Jul-2020 and correct it in the UDF?

@mLipok, see if you think this is an acceptable solution to @DonChunior's problem:

; #FUNCTION# ====================================================================================================================
; Name ..........: _XML_UpdateField
; Description ...: Update existing single node based on XPath specs.
; Syntax ........: _XML_UpdateField(ByRef $oXmlDoc, $sXPath, $sData)
; Parameters ....: $oXmlDoc   - [in/out] an object. A valid DOMDocument or IXMLDOMElement object
;                  $sXPath    - a string value. The XML tree path from root node (root/child/child..)
;                  $sData     - The data to update the node with.
; Return values .: On Success - Returns $XML_RET_SUCCESS
;                  On Failure - Returns $XML_RET_FAILURE and sets the @error flag to non-zero (look in #Region XML.au3 - ERROR Enums)
; Author ........: Eltorro
; Modified ......: Weaponx, mLipok, GMK
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; [yes/no]
; ===============================================================================================================================
Func _XML_UpdateField(ByRef $oXmlDoc, $sXPath, $sData)
    ; Error handler, automatic cleanup at end of function
    Local $oXML_COM_ErrorHandler = ObjEvent("AutoIt.Error", __XML_ComErrorHandler_InternalFunction)
    #forceref $oXML_COM_ErrorHandler

    Local $oNode_Selected = _XML_SelectSingleNode($oXmlDoc, $sXPath)
    If @error Then Return SetError(@error, @extended, $XML_RET_FAILURE)
    If Not $oNode_Selected.hasChildNodes And $oNode_Selected.nodetype <> $XML_NODE_ELEMENT And $oNode_Selected.nodetype <> $XML_NODE_TEXT Then _
            Return SetError($XML_ERR_INVALIDNODETYPE, $XML_EXT_DEFAULT, $XML_RET_FAILURE)

    If $oNode_Selected.hasChildNodes Then
        Local $bUpdateStatus = False
        For $oNode_enum_Child In $oNode_Selected.childNodes()
            If $oNode_enum_Child.nodetype = $XML_NODE_ELEMENT OR $oNode_enum_Child.nodetype = $XML_NODE_TEXT Then
                $oNode_enum_Child.Text = $sData
                $bUpdateStatus = True
                ExitLoop
            EndIf
        Next

        If Not $bUpdateStatus Then
            Local $oNode_Created = $oXmlDoc.createTextNode($sData)
            $oNode_Selected.appendChild($oNode_Created)
            If @error Then Return SetError($XML_ERR_NODEAPPEND, @error, $XML_RET_FAILURE)
        EndIf

    ElseIf $oNode_Selected.nodetype = $XML_NODE_ELEMENT OR $oNode_Selected.nodetype = $XML_NODE_TEXT Then
        $oNode_Selected.Text = $sData
    EndIf

    Return SetError($XML_ERR_OK, $XML_EXT_DEFAULT, $XML_RET_SUCCESS)
EndFunc   ;==>_XML_UpdateField

 

Edited by GMK
Error $XML_ERR_INVALIDNODETYPE

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
×
×
  • Create New...