marko001 Posted March 17, 2021 Share Posted March 17, 2021 Hi all guys, I'm not able, using XML.au3, to retrieve data, array format, of nested nodes. Here is the example.XML I use: <Main> <FirstName>Name</FirstName> <LastName>1</LastName> <AddressVerified>True</AddressVerified> <IDVerified>True</IDVerified> <RoomTypes> <Roomtype 1="RoomA" 2="RoomC" 3="RoomE" 4="RoomG" /> <Roomtype 1="RoomB" 2="RoomD" 3="RoomF" 4="RoomH" /> </RoomTypes> <SubMenu> <Children>1</Children> <Pets>2</Pets> <Furnitures> <Furniture Name="Name1" Location="Room1" Price="100" /> <Furniture Name="Name2" Location="Room1" Price="300" /> <Furniture Name="Name3" Location="Room2" Price="500" /> </Furnitures> </SubMenu> </Main> And here is the code where I can retrieve only first node datas: expandcollapse popup#include <array.au3> #include <date.au3> #include <MsgBoxConstants.au3> #include "XML.au3" ; This COM Error Hanlder will be used globally (excepting inside UDF Functions) Global $oErrorHandler = ObjEvent("AutoIt.Error", ErrFunc_CustomUserHandler_MAIN) #forceref $oErrorHandler ; This is SetUp for the transfer UDF internal COM Error Handler to the user function _XML_ComErrorHandler_UserFunction(ErrFunc_CustomUserHandler_XML) Local $sXML_FileFullPath = @ScriptDir & "\Example.xml" Local $oXMLDoc = _XML_CreateDOMDocument(3) _XML_Load($oXMLDoc, $sXML_FileFullPath, "", False) Local $sXPath = "//FirstName" Local $avalues = _XML_GetValue($oXmlDoc, $sXPath) _ArrayDisplay($avalues) ; -- WORKS Local $sXPath1 = "//Furnitures" Local $oNodesColl = _XML_GetChildNodes($oXmlDoc, $sXPath1) Local $aNodesColl = _XML_Array_GetNodesProperties($oNodesColl) _ArrayDisplay($aNodesColl), 'Example_6__XML_GetChildNodes: ' & 'Length=' & $oNodesColl.length & ' XPath=' & $oNodesColl.expr) #Region XML__Examples.au3 - XML DOM Error/Event Handling Func ErrFunc_CustomUserHandler_MAIN($oError) ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : MainScript ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>ErrFunc_CustomUserHandler_MAIN Func ErrFunc_CustomUserHandler_XML($oError) ; here is declared another path to UDF au3 file ; thanks to this with using _XML_ComErrorHandler_UserFunction(ErrFunc_CustomUserHandler_XML) ; you get errors which after pressing F4 in SciTE4AutoIt you goes directly to the specified UDF Error Line ConsoleWrite(@ScriptDir & '\XML.au3' & " (" & $oError.scriptline & ") : UDF ==> COM Error intercepted ! " & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>ErrFunc_CustomUserHandler_XML ; #FUNCTION# ==================================================================================================================== ; Name ..........: XML_My_ErrorParser ; Description ...: Changing $XML_ERR_ ... to human readable description ; Syntax ........: XML_My_ErrorParser($iXMLWrapper_Error, $iXMLWrapper_Extended) ; Parameters ....: $iXMLWrapper_Error - an integer value. ; $iXMLWrapper_Extended - an integer value. ; Return values .: description as string ; Author ........: mLipok ; Modified ......: ; Remarks .......: This function is only example of how user can parse @error and @extended to human readable description ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func XML_My_ErrorParser($iXMLWrapper_Error, $iXMLWrapper_Extended = 0) Local $sErrorInfo = '' Switch $iXMLWrapper_Error Case $XML_ERR_SUCCESS $sErrorInfo = '$XML_ERR_SUCCESS=' & $XML_ERR_SUCCESS & @CRLF & 'All is ok.' Case $XML_ERR_GENERAL $sErrorInfo = '$XML_ERR_GENERAL=' & $XML_ERR_GENERAL & @CRLF & 'The error which is not specifically defined.' Case $XML_ERR_COMERROR $sErrorInfo = '$XML_ERR_COMERROR=' & $XML_ERR_COMERROR & @CRLF & 'COM ERROR OCCURED. Check @extended and your own error handler function for details.' Case $XML_ERR_ISNOTOBJECT $sErrorInfo = '$XML_ERR_ISNOTOBJECT=' & $XML_ERR_ISNOTOBJECT & @CRLF & 'No object passed to function' Case $XML_ERR_INVALIDDOMDOC $sErrorInfo = '$XML_ERR_INVALIDDOMDOC=' & $XML_ERR_INVALIDDOMDOC & @CRLF & 'Invalid object passed to function' Case $XML_ERR_INVALIDATTRIB $sErrorInfo = '$XML_ERR_INVALIDATTRIB=' & $XML_ERR_INVALIDATTRIB & @CRLF & 'Invalid object passed to function.' Case $XML_ERR_INVALIDNODETYPE $sErrorInfo = '$XML_ERR_INVALIDNODETYPE=' & $XML_ERR_INVALIDNODETYPE & @CRLF & 'Invalid object passed to function.' Case $XML_ERR_OBJCREATE $sErrorInfo = '$XML_ERR_OBJCREATE=' & $XML_ERR_OBJCREATE & @CRLF & 'Object can not be created.' Case $XML_ERR_NODECREATE $sErrorInfo = '$XML_ERR_NODECREATE=' & $XML_ERR_NODECREATE & @CRLF & 'Can not create Node - check also COM Error Handler' Case $XML_ERR_NODEAPPEND $sErrorInfo = '$XML_ERR_NODEAPPEND=' & $XML_ERR_NODEAPPEND & @CRLF & 'Can not append Node - check also COM Error Handler' Case $XML_ERR_PARSE $sErrorInfo = '$XML_ERR_PARSE=' & $XML_ERR_PARSE & @CRLF & 'Error: with Parsing objects, .parseError.errorCode=' & $iXMLWrapper_Extended & ' Use _XML_ErrorParser_GetDescription() for get details.' Case $XML_ERR_PARSE_XSL $sErrorInfo = '$XML_ERR_PARSE_XSL=' & $XML_ERR_PARSE_XSL & @CRLF & 'Error with Parsing XSL objects .parseError.errorCode=' & $iXMLWrapper_Extended & ' Use _XML_ErrorParser_GetDescription() for get details.' Case $XML_ERR_LOAD $sErrorInfo = '$XML_ERR_LOAD=' & $XML_ERR_LOAD & @CRLF & 'Error opening specified file.' Case $XML_ERR_SAVE $sErrorInfo = '$XML_ERR_SAVE=' & $XML_ERR_SAVE & @CRLF & 'Error saving file.' Case $XML_ERR_PARAMETER $sErrorInfo = '$XML_ERR_PARAMETER=' & $XML_ERR_PARAMETER & @CRLF & 'Wrong parameter passed to function.' Case $XML_ERR_ARRAY $sErrorInfo = '$XML_ERR_ARRAY=' & $XML_ERR_ARRAY & @CRLF & 'Wrong array parameter passed to function. Check array dimension and conent.' Case $XML_ERR_XPATH $sErrorInfo = '$XML_ERR_XPATH=' & $XML_ERR_XPATH & @CRLF & 'XPath syntax error - check also COM Error Handler.' Case $XML_ERR_NONODESMATCH $sErrorInfo = '$XML_ERR_NONODESMATCH=' & $XML_ERR_NONODESMATCH & @CRLF & 'No nodes match the XPath expression' Case $XML_ERR_NOCHILDMATCH $sErrorInfo = '$XML_ERR_NOCHILDMATCH=' & $XML_ERR_NOCHILDMATCH & @CRLF & 'There is no Child in nodes matched by XPath expression.' Case $XML_ERR_NOATTRMATCH $sErrorInfo = '$XML_ERR_NOATTRMATCH=' & $XML_ERR_NOATTRMATCH & @CRLF & 'There is no such attribute in selected node.' Case $XML_ERR_DOMVERSION $sErrorInfo = '$XML_ERR_DOMVERSION=' & $XML_ERR_DOMVERSION & @CRLF & 'DOM Version: ' & 'MSXML Version ' & $iXMLWrapper_Extended & ' or greater required for this function' Case $XML_ERR_EMPTYCOLLECTION $sErrorInfo = '$XML_ERR_EMPTYCOLLECTION=' & $XML_ERR_EMPTYCOLLECTION & @CRLF & 'Collections of objects was empty' Case $XML_ERR_EMPTYOBJECT $sErrorInfo = '$XML_ERR_EMPTYOBJECT=' & $XML_ERR_EMPTYOBJECT & @CRLF & 'Object is empty' Case Else $sErrorInfo = '=' & $iXMLWrapper_Error & @CRLF & 'NO ERROR DESCRIPTION FOR THIS @error' EndSwitch Local $sExtendedInfo = '' Switch $iXMLWrapper_Error Case $XML_ERR_COMERROR, $XML_ERR_NODEAPPEND, $XML_ERR_NODECREATE $sExtendedInfo = 'COM ERROR NUMBER (@error returned via @extended) =' & $iXMLWrapper_Extended Case $XML_ERR_PARAMETER $sExtendedInfo = 'This @error was fired by parameter: #' & $iXMLWrapper_Extended Case Else Switch $iXMLWrapper_Extended Case $XML_EXT_DEFAULT $sExtendedInfo = '$XML_EXT_DEFAULT=' & $XML_EXT_DEFAULT & @CRLF & 'Default - Do not return any additional information' Case $XML_EXT_XMLDOM $sExtendedInfo = '$XML_EXT_XMLDOM=' & $XML_EXT_XMLDOM & @CRLF & '"Microsoft.XMLDOM" related Error' Case $XML_EXT_DOMDOCUMENT $sExtendedInfo = '$XML_EXT_DOMDOCUMENT=' & $XML_EXT_DOMDOCUMENT & @CRLF & '"Msxml2.DOMDocument" related Error' Case $XML_EXT_XSLTEMPLATE $sExtendedInfo = '$XML_EXT_XSLTEMPLATE=' & $XML_EXT_XSLTEMPLATE & @CRLF & '"Msxml2.XSLTemplate" related Error' Case $XML_EXT_SAXXMLREADER $sExtendedInfo = '$XML_EXT_SAXXMLREADER=' & $XML_EXT_SAXXMLREADER & @CRLF & '"MSXML2.SAXXMLReader" related Error' Case $XML_EXT_MXXMLWRITER $sExtendedInfo = '$XML_EXT_MXXMLWRITER=' & $XML_EXT_MXXMLWRITER & @CRLF & '"MSXML2.MXXMLWriter" related Error' Case $XML_EXT_FREETHREADEDDOMDOCUMENT $sExtendedInfo = '$XML_EXT_FREETHREADEDDOMDOCUMENT=' & $XML_EXT_FREETHREADEDDOMDOCUMENT & @CRLF & '"Msxml2.FreeThreadedDOMDocument" related Error' Case $XML_EXT_XMLSCHEMACACHE $sExtendedInfo = '$XML_EXT_XMLSCHEMACACHE=' & $XML_EXT_XMLSCHEMACACHE & @CRLF & '"Msxml2.XMLSchemaCache." related Error' Case $XML_EXT_STREAM $sExtendedInfo = '$XML_EXT_STREAM=' & $XML_EXT_STREAM & @CRLF & '"ADODB.STREAM" related Error' Case $XML_EXT_ENCODING $sExtendedInfo = '$XML_EXT_ENCODING=' & $XML_EXT_ENCODING & @CRLF & 'Encoding related Error' Case Else $sExtendedInfo = '$iXMLWrapper_Extended=' & $iXMLWrapper_Extended & @CRLF & 'NO ERROR DESCRIPTION FOR THIS @extened' EndSwitch EndSwitch ; return back @error and @extended for further debuging Return SetError($iXMLWrapper_Error, $iXMLWrapper_Extended, _ '@error description:' & @CRLF & _ $sErrorInfo & @CRLF & _ @CRLF & _ '@extended description:' & @CRLF & _ $sExtendedInfo & @CRLF & _ '') EndFunc ;==>XML_My_ErrorParser #EndRegion XML__Examples.au3 - XML DOM Error/Event Handling I would like to get all these info and store them on one or more arrays, no matter, but seems I miss something since I can't retrieve them. Thanks all in advance, Marco Link to comment Share on other sites More sharing options...
TheXman Posted March 17, 2021 Share Posted March 17, 2021 (edited) To start with, the example XML that you posted is incomplete and invalid. It does not have an XML tag at the beginning AND you cannot have attribute names like 1, 2, and 3. XML element names must start with a letter or an underscore. Whenever you get your XML issues worked out, the examples I posted in the topics below are a few ways, using the xml.au3 UDF, to process XML data into one or more arrays: 3 hours ago, marko001 said: I would like to get all these info and store them on one or more arrays, no matter, but seems I miss something since I can't retrieve them. For the record, a simple search of the forum, using just "xml AND array", would have lead you to the topics above. https://www.autoitscript.com/forum/search/?q=xml AND array&quick=1 Edited March 18, 2021 by TheXman Added 2nd example link CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
marko001 Posted March 18, 2021 Author Share Posted March 18, 2021 Thanks a lot @TheXman, I'll look at your example and be back to you in case I can't sort it out. Sorry for my poor search... I didn't think to use the "array" word in my searchs so I didn't get your posts Link to comment Share on other sites More sharing options...
marko001 Posted March 18, 2021 Author Share Posted March 18, 2021 @TheXman I pretty understood how to manage arrays for certain kind of nodes. I'm still in a mess for nodes like these: <SubMenu> <Children>1</Children> <Pets>2</Pets> <Furnitures> <Furniture Name="Name1" Location="Room1" Price="100" /> <Furniture Name="Name2" Location="Room1" Price="300" /> <Furniture Name="Name3" Location="Room2" Price="500" /> </Furnitures> </SubMenu> I can put in arrays "Children" and "Pets" but i'm not able to retrieve info from <Furnitures> My aim is to get an array like $aSubMenu_Furnitures[0][3] ; x,0 - Name ; x,1 - Location ; x,2 - Price So in my case I should get a [3][3] array $aSubMenu_Furnitures[3][3] ; 0,0 - Name1 ; 0,1 - Room1 ; 0,2 - 100 ; 1,0 - Name2 ; 1,1 - Room1 ; 1,2 - 300 ; 2,0 - Name3 ; 2,1 - Room2 ; 2,2 - 500 Thanks, dude Link to comment Share on other sites More sharing options...
TheXman Posted March 18, 2021 Share Posted March 18, 2021 (edited) I already provided 2 well-documented examples, using the xml.au3 udf, of how to process XML elements into an arrays. Both of the examples that I provided are very similar to the structures you have given as an example. For the most part, it's just a matter of understanding the logic, changing the names, and making a few small changes to fit your particular case. So you need to be more specific as to what problem or problems you're having. I'm not going to try to guess. If you would like my help in learning why you are having those problems and how you may be able to resolve them, then post your script (or a short example) and the valid XML that you're using so it can be analyzed. Edited March 18, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
marko001 Posted March 18, 2021 Author Share Posted March 18, 2021 @TheXman Hi bro! I got it! I simply needed to use "@" to get the specific field. $aRoomName = _XML_GetValue($oXml, "//Furnitures/@Name") $aRoomLocation = _XML_GetValue($oXml, "//Furnitures/@Location") $aRoomPrice = _XML_GetValue($oXml, "//Furnitures/@Price") Last question (You already answered all of previous ones thanks to the links you provided): If I have "n" submenus, like in this case: <SubMenu> <Children>1</Children> <Pets>2</Pets> <Furnitures> <Furniture Name="Name1" Location="Room1" Price="100" /> <Furniture Name="Name2" Location="Room1" Price="300" /> <Furniture Name="Name3" Location="Room2" Price="500" /> </Furnitures> </SubMenu> <SubMenu> <Children>2</Children> <Pets>2</Pets> <Furnitures> <Furniture Name="Name1" Location="Room1" Price="100" /> <Furniture Name="Name2" Location="Room1" Price="300" /> <Furniture Name="Name3" Location="Room2" Price="500" /> </Furnitures> </SubMenu> how can I get, for example, Furnitures in case we have 2 Children? (<Children>2</Children>) Is this the correct form? : $aDetailedFurniture = _XML_GetValue($oXml, "//SubProfile/[Children='2']/Furnitures/Furniture/@Name") Link to comment Share on other sites More sharing options...
TheXman Posted March 18, 2021 Share Posted March 18, 2021 (edited) 14 minutes ago, marko001 said: I got it! I simply needed to use "@" to get the specific field. Congrats! The "@" designates XML attributes. 14 minutes ago, marko001 said: how can I get, for example, Furnitures in case we have 2 Children? (<Children>2</Children>) There are numerous ways. What would help is if you described what the expected result should look like. Again, the examples that I have already provided show how to process nested arrays (with both static and dynamic numbers of elements). As I said before, if you want my help, you need to show your script (or at least a valid attempt) so I can understand what you are having an issue with. Note that I did not say random lines of code without context, I said a script. Edited March 18, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
marko001 Posted March 18, 2021 Author Share Posted March 18, 2021 @TheXman Here we go, I tried to explain also in Console: <?xml version="1.0" encoding="utf-8"?> <Main> <FirstName>Francois</FirstName> <LastName>Rens</LastName> <AddressVerified>True</AddressVerified> <IDVerified>True</IDVerified> <RoomTypes> <Roomtype A="RoomA" B="RoomC" C="RoomE" D="RoomG" /> <Roomtype A="RoomB" B="RoomD" C="RoomF" D="RoomH" /> </RoomTypes> <SubMenu> <Children>1</Children> <Pets>2</Pets> <Furnitures> <Furniture Name="Name1" Location="Room1" Price="100" /> <Furniture Name="Name2" Location="Room1" Price="300" /> <Furniture Name="Name3" Location="Room2" Price="500" /> </Furnitures> </SubMenu> <SubMenu> <Children>2</Children> <Pets>2</Pets> <Furnitures> <Furniture Name="Name4" Location="Room2" Price="400" /> <Furniture Name="Name5" Location="Room1" Price="600" /> <Furniture Name="Name6" Location="Room3" Price="800" /> </Furnitures> </SubMenu> </Main> and expandcollapse popup#include <Constants.au3> #include <Array.au3> #include <xml.au3> _testXML() Func _testXML() Const $XML_FILE = @ScriptDir & "\Demofile.xml" Local $oXML, $oRecord, $oSubRecord ;vars for main Tree Local $aRecord[0][4] Local $sFirstName, $sLastName, $sAddressVerified, $sIDVerified ;vars for SubMenu Local $aSubMenu[0][2] Local $sChildren, $sPets ;vars for Furnitures Local $aFurnitures[0][3] ;Create XML object $oXML = _XML_CreateDOMDocument() If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "XML object creation failed - @error = " & @error) ;Load xml file _XML_Load($oXML, $XML_FILE) If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Loading of XML failed - @error = " & @error) ;Get Main Record Data $oRecord = _XML_SelectNodes($oXML, "//Main") If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Error getting contact nodes - @error = " & @error) ;Load contact information into the array For $val In $oRecord ;Populate the fields $sFirstName = _XML_GetValue($val, "FirstName")[1] $sLastName = _XML_GetValue($val, "LastName")[1] $sAddressVerified = _XML_GetValue($val, "AddressVerified")[1] $sIDVerified = _XML_GetValue($val, "IDVerified")[1] _ArrayAdd($aRecord, _ $sFirstName & "|" & _ $sLastName & "|" & _ $sAddressVerified & "|" & _ $sIDVerified) Next _ArrayDisplay($aRecord, "Main Data", "", 0, Default, "First Name|Last Name|Address Verified|ID Verified") ; Search on SubMenu $oSubRecord = _XML_SelectNodes($oXML, "/Main/SubMenu") If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Error getting contact nodes - @error = " & @error) ;Load contact information into the array For $val In $oSubRecord $sChildren = _XML_GetValue($val, "Children")[1] $sPets = _XML_GetValue($val, "Pets")[1] _ArrayAdd($aSubMenu, _ $sChildren & "|" & _ $sPets) Next ConsoleWrite("Array shows me both SubMenus, how can I show just, for example, the first?" & @CRLF) _ArrayDisplay($aSubMenu, "Example of a Submenu Data", "", 0, Default, "Children|Pets") ; Arrays of attributes $aF1 = _XML_GetValue($oXml, "//Furniture/@Name") $aF2 = _XML_GetValue($oXml, "//Furniture/@Location") $aF3 = _XML_GetValue($oXml, "//Furniture/@Price") ReDim $aFurnitures[UBound($aF1)-1][3] for $i = 1 to UBound($aF1)-1 $aFurnitures[$i-1][0] = $aF1[$i] $aFurnitures[$i-1][1] = $aF2[$i] $aFurnitures[$i-1][2] = $aF3[$i] Next ConsoleWrite("Also in this case I see both SubMenus" & @CRLF) _ArrayDisplay($aFurnitures, "Furnitures") ; Try to get specific Furniture - I want to get Furnitures when Children = 2 $ans = InputBox("Children","How Many Children?","2") ;~ $row = _ArraySearch($aSubMenu,$ans,0,0,0,0,1,1) $aQueryResult = _XML_GetValue($oXml, "//SubMenu/[Children='" & $ans &"']/Furniture/@Name") If @error Then MsgBox(0,"Error","Error N. " & @error) Else _ArrayDisplay($aQueryResult) EndIf EndFunc Link to comment Share on other sites More sharing options...
TheXman Posted March 18, 2021 Share Posted March 18, 2021 (edited) Like I said, it would help to know what the expected resulting array should look like to know how I would process the xml file. Below is an example that will hopefully get you pointed in the right direction. I tried to make the structure similar to what you are working with. expandcollapse popup#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #include <Constants.au3> #include <Array.au3> #include <MyIncludes\XML\xml.au3> ;<== Modify as needed xml_example() Func xml_example() Const $XML_DATA = _ '<?xml version="1.0" encoding="UTF-8" ?>' & _ '<Root>' & _ ' <Store id="1" name="Store 1">' & _ ' <Bags>' & _ ' <Bag Name="Brand X" Cost="30.00" />' & _ ' </Bags>' & _ ' <Bikes>' & _ ' <Bike Name="Huffy" Color="Red" Cost="100.00" />' & _ ' <Bike Name="Schwin" Color="Blue" Cost="150.00" />' & _ ' <Bike Name="Bianchi" Color="Green" Cost="300.00" />' & _ ' </Bikes>' & _ ' </Store>' & _ ' <Store id="2" name="Store 2">' & _ ' <Bikes>' & _ ' <Bike Name="Aprilla" Color="Red" Cost="150.00" />' & _ ' <Bike Name="Acme" Color="Green" Cost="275.00" />' & _ ' <Bike Name="Bianchi" Color="Silver" Cost="300.00" />' & _ ' </Bikes>' & _ ' </Store>' & _ '</Root>' Local $oXML, $oStores, $oBikes Local $iIndex Local $aBikes[0][4] Local $sStoreName ;Create XML object $oXML = _XML_CreateDOMDocument() If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "XML object creation failed - @error = " & @error) ;Load the xml into the xml object _XML_LoadXML($oXML, $XML_DATA) If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Loading of XML failed - @error = " & @error) ;Get collection of store nodes $oStores = _XML_SelectNodes($oXML, "//Root/Store") If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Error getting nodes - @error = " & @error) ;For each store node, load bike information into the array $iIndex = -1 For $oStore in $oStores ;Save store name $sStoreName = _XML_GetValue($oStore, "@name")[1] ;Get collection of bike nodes in store $oBikes = _XML_SelectNodes($oStore, "./Bikes/Bike") If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Error getting nodes - @error = " & @error) ;For each bike node, load information into the array For $oBike in $oBikes ;Add a row to the array and increment the row index _ArrayAdd($aBikes, "") $iIndex += 1 ;Populate row columns with values of interest $aBikes[$iIndex][0] = $sStoreName $aBikes[$iIndex][1] = _XML_GetValue($oBike, "@Name")[1] $aBikes[$iIndex][2] = _XML_GetValue($oBike, "@Color")[1] $aBikes[$iIndex][3] = _XML_GetValue($oBike, "@Cost")[1] Next Next ;Display furnitures array _ArrayDisplay($aBikes, "Bikes by Store", "", 0, Default, "Store|Name|Color|Cost") EndFunc Edited March 18, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
marko001 Posted March 18, 2021 Author Share Posted March 18, 2021 (edited) So, if I want to get all bikes available in Store1 I just get it from the resulting array? In this way I have to load *all* the items in one array. Is it possible to query it and load only what needed? Let's say I would like to see only bikes on Store 1 Edit: and... by the way...Bianchi always the most expensive Edited March 18, 2021 by marko001 Link to comment Share on other sites More sharing options...
TheXman Posted March 18, 2021 Share Posted March 18, 2021 (edited) You could specify the xpath to retrieve the bike nodes under store 1 in several ways, for example: /Root/Store[1]/Bikes/Bike or //Store[1]/Bikes/Bike or /Root/Store[@name='Store 1']/Bikes/Bike (By value) expandcollapse popup#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #include <Constants.au3> #include <xml.au3> Const $XML_DATA = _ '<?xml version="1.0" encoding="UTF-8" ?>' & _ '<Root>' & _ ' <Store id="1" name="Store 1">' & _ ' <Address>1234 Any St, Any Town, ABC 48034</Address>' & _ ' <Bags>' & _ ' <Bag Name="Brand X" Cost="30.00" />' & _ ' </Bags>' & _ ' <Bikes>' & _ ' <Bike Name="Huffy" Color="Red" Cost="100.00" />' & _ ' <Bike Name="Schwin" Color="Blue" Cost="150.00" />' & _ ' <Bike Name="Bianchi" Color="Green" Cost="300.00" />' & _ ' </Bikes>' & _ ' </Store>' & _ ' <Store id="2" name="Store 2">' & _ ' <Address>7890 Any Ave, Biketown, ABC 90210</Address>' & _ ' <Bikes>' & _ ' <Bike Name="Aprilla" Color="Red" Cost="150.00" />' & _ ' <Bike Name="Acme" Color="Green" Cost="275.00" />' & _ ' <Bike Name="Bianchi" Color="Silver" Cost="300.00" />' & _ ' </Bikes>' & _ ' </Store>' & _ '</Root>' xml_example() Func xml_example() Local $oXML, $oNodeCollection ;Create XML object $oXML = _XML_CreateDOMDocument() If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "XML object creation failed - @error = " & @error) ;Load the xml into the xml object _XML_LoadXML($oXML, $XML_DATA) If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Loading of XML failed - @error = " & @error) ;Get collection of nodes $oNodeCollection = _XML_SelectNodes($oXML, "/Root/Store[1]/Bikes/Bike") ;By index ;$oNodeCollection = _XML_SelectNodes($oXML, "/Root/Store[@name='Store 1']/Bikes/Bike ") ;By value If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Error getting nodes - @error = " & @error) ConsoleWrite("Store 1 Bikes" & @CRLF) ;For each node in the collection For $oNode in $oNodeCollection ConsoleWrite(_XML_GetValue($oNode, "@Name")[1] & @CRLF) Next EndFunc Console Store 1 Bikes Huffy Schwin Bianchi Edited March 19, 2021 by TheXman Added example CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
marko001 Posted March 18, 2021 Author Share Posted March 18, 2021 @TheXman I saw your XML is <Store id="1" name="Store 1">' <Store id="1" name="Store 1"> .. </Store> my one is <Store> <id>1</id> <name>Store 1</name> ... </Store> How can I filter using this format? I tried local aFurnitures[0][3] for $oStore in $oStore $sID = _XML_GetValue($oStore,"ID")[1] If $sID = 1 Then $aF1 = _XML_GetValue($oStore, "//Bike/@name") $aF2 = _XML_GetValue($oStore, "//Bike/@Color") $aF3 = _XML_GetValue($oStore, "//Bike/@Cost") ReDim $aFurnitures[UBound($aF1)-1][3] for $i = 1 to UBound($aF1)-1 $aFurnitures[$i-1][0] = $aF1[$i] $aFurnitures[$i-1][1] = $aF2[$i] $aFurnitures[$i-1][2] = $aF3[$i] Next EndIf _ArrayDisplay($aFurnitures) Exit Next This gives me a strange result: I get the first store, $sID = 1, so If cycle is processed. But I get bikes data from second store, not first one I tried also $aF1 = _XML_GetValue($oStore, "/[ID='1']/Bike/@name") but with no success Link to comment Share on other sites More sharing options...
TheXman Posted March 18, 2021 Share Posted March 18, 2021 (edited) $oNodeCollection = _XML_SelectNodes($oXML, "/Root/Store[id='1']/Bikes/Bike") ;By value XML is case-sensitive. If you want a dance partner, then you should go to a club. 😉 I'm getting tired of this back & forth, step-by-step little dance your doing in order to to get to some yet unknown destination/solution. You keep moving the target and changing the structure of the XML. I think you have enough to work with now. If you have any more questions, they need to be well thought out and include all the necessary details including YOUR XML in the format and structure that it exists, a specific question or questions, and specific expected results. If you want to learn more about xpath, try the XPATH Tutorial on the W3Schools site. I don't have a problem helping you learn, but you need to be way more focused because I don't have a lot of patience and don't like wasting my time by chasing moving targets. "I'm too old to be chasing targets. It's much easier to shoot them and be done with it." ~TheXman 😉 Edited March 18, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
marko001 Posted March 18, 2021 Author Share Posted March 18, 2021 @TheXman Thanks for your answer. But my XML was quite clear, and I tried to convert to your XML since you posted a different one. <SubMenu> <Children>1</Children> <Pets>2</Pets> <Furnitures> <Furniture Name="Name1" Location="Room1" Price="100" /> <Furniture Name="Name2" Location="Room1" Price="300" /> <Furniture Name="Name3" Location="Room2" Price="500" /> </Furnitures> </SubMenu> <SubMenu> <Children>2</Children> <Pets>2</Pets> <Furnitures> <Furniture Name="Name4" Location="Room2" Price="400" /> <Furniture Name="Name5" Location="Room1" Price="600" /> <Furniture Name="Name6" Location="Room3" Price="800" /> </Furnitures> </SubMenu> My intention is, without loading the entire XML into an array, to retrieve Name, Location and Price of the three Furnitures if Children = 2, nothing less, nothing more. Then we can dance, everyone in a separate club A big hug, dude! Link to comment Share on other sites More sharing options...
TheXman Posted March 18, 2021 Share Posted March 18, 2021 (edited) expandcollapse popup#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #include <Constants.au3> #include <Array.au3> #include <MyIncludes\XML\xml.au3> ;<== Modify as needed Const $XML_DATA = _ '<?xml version="1.0" encoding="UTF-8" ?>' & _ '<Root>' & _ ' <SubMenu>' & _ ' <Children>1</Children>' & _ ' <Pets>2</Pets>' & _ ' <Furnitures>' & _ ' <Furniture Name="Name1" Location="Room1" Price="100" />' & _ ' <Furniture Name="Name2" Location="Room1" Price="300" />' & _ ' <Furniture Name="Name3" Location="Room2" Price="500" />' & _ ' </Furnitures>' & _ ' </SubMenu>' & _ ' <SubMenu>' & _ ' <Children>2</Children>' & _ ' <Pets>2</Pets>' & _ ' <Furnitures>' & _ ' <Furniture Name="Name4" Location="Room2" Price="400" />' & _ ' <Furniture Name="Name5" Location="Room1" Price="600" />' & _ ' <Furniture Name="Name6" Location="Room3" Price="800" />' & _ ' </Furnitures>' & _ ' </SubMenu>' & _ '</Root>' xml_example() Func xml_example() Local $oXML, $oNodeCollection Local $aFurniture[0][3] ;Create XML object $oXML = _XML_CreateDOMDocument() If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "XML object creation failed - @error = " & @error) ;Load the xml into the xml object _XML_LoadXML($oXML, $XML_DATA) If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Loading of XML failed - @error = " & @error) ;Get collection of nodes $oNodeCollection = _XML_SelectNodes($oXML, "/Root/SubMenu[Children = '2']/Furnitures/Furniture ") If @error Then Exit MsgBox($MB_ICONERROR, "ERROR", "Error getting nodes - @error = " & @error) ;For each node in the collection For $oNode in $oNodeCollection _ArrayAdd($aFurniture, _ _XML_GetValue($oNode, "@Name")[1] & _ "|" & _XML_GetValue($oNode, "@Location")[1] & _ "|" & _XML_GetValue($oNode, "@Price")[1]) Next _ArrayDisplay($aFurniture, "Furniture for Children = 2", "", 0, Default, "Name|Location|Price") EndFunc 2 hours ago, marko001 said: My intention is, without loading the entire XML into an array, to retrieve Name, Location and Price of the three Furnitures if Children = 2, nothing less, nothing more. Then we can dance, everyone in a separate club Well, I guess you can go to the club now. Edited March 18, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
marko001 Posted March 18, 2021 Author Share Posted March 18, 2021 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now