jdelaney Posted August 13, 2015 Author Posted August 13, 2015 (edited) Here we go!...Got the [#] or [last()] conditions working...currently, it's simplistic, but the xpath your provided will function.I also put in logic to allow for [last()-#], so instead of the last node, it will grab the 3rd to last...Here are the new functions, and a sample of navigating through the new autoit forum, to the general help and support page, and then navigating the the 6th page...which is the last()-3:$xpathGeneralHelpPagination = "//ul[@class='ipsPagination']/li[last()-3]/a"using the same xpath, but wanting to grab the 3rd link would be$xpathGeneralHelpPagination = "//ul[@class='ipsPagination']/li[3]/a"expandcollapse popup#region SCITE_CallTipsForFunctions ;BGe_IEGetDOMObjByXPathWithAttributes($oIEObj, $sXPath, [$iMaxWait=2000]) Return array of objects on browser matching callers xpath #endregion SCITE_CallTipsForFunctions #include <ie.au3> #include <array.au3> #region GLOBALVariables Global $gbBGe_PerformConsoleWrites = True ; The XPath array to work with will be 2d, with the following Global Enum $giBGe_XPath_Dim2_sRawNode, _ $giBGe_XPath_Dim2_sNodeName, _ $giBGe_XPath_Dim2_bNodeIsRelative, _ $giBGe_XPath_Dim2_sRawNodeConstraints, _ $giBGe_XPath_Dim2_bIsConstrainted, _ $giBGe_XPath_Dim2_aNodeConstraints, _ $giBGe_XPath_Dim2_iPredicateReturn, _ $giBGe_XPath_Dim2_UBound ;~ now know for sure it goes here...so contstraints is FALSE...only going to use node name for now ;~ check this early in the loop and use the actual colections of the nodes...logically loop through the proper direction ; $giBGe_XPath_Dim2_aNodeConstraints will contain a 2d, with the following Global Enum $giBGe_Constraint_Dim2_sNodeName, _ $giBGe_Constraint_Dim2_bIsAttribute, _ $giBGe_Constraint_Dim2_bIsSelf, _ $giBGe_Constraint_Dim2_sNodeValue, _ $giBGe_Constraint_Dim2_bIsContains, _ $giBGe_Constraint_Dim2_iPredicateReturn, _ $giBGe_Constraint_Dim2_UBound ; Regexp to split xpath Global $gsBGe_RegExpNodeSplit = "(?U)(.*(?:['""].*['""].*){0,})(?:\/)" ; Split Xpath into nodes...split by / where it is part of x-path Global $gsBGe_RegExpNodeAndCondSplit = "([^\[\]]+)\[(.*)\]" ; Get node name and conditions...conditions can be empty Global $gsBGe_RegExpOrSplit = "(?i)(?U)(.*['""].*['""\)])(?:\sor\s)|.{1,}?" ; Split Or statements inside [] Global $gsBGe_RegExpAndSplit = "(?i)(?U)(.*['""].*['""\)])(?:\sand\s)|.{1,}?" ; Split And statements inside [] Global $gsBGe_RegExpSplitContains = "(?i)contains\s*\(\s*(.+)\s*,\s*['""](.+)['""]\s*\)" ; Split contains, remove spaces that are not needed Global $gsBGe_RegExpSplitNonContains = "(.*)\s*\=\s*['""](.*)['""]" ; Split constraint that is not a contains, remove spaces that are not needed Global $gsBGe_RegExpNodeSplit = "(?U)(.*(?:['""].*['""].*){0,})(?:\/)" ; Split Xpath into nodes...split by / where it is part of x-path Global $gsBGe_RegExpNodeAndCondSplit = "([^\[\]]+)\[(.*)\]" ; Get node name and conditions...conditions can be empty Global $gsBGe_RegExpOrSplit = "(?i)(?U)(.*['""].*['""\)])(?:\sor\s)|.{1,}?" ; Split Or statements inside [] Global $gsBGe_RegExpAndSplit = "(?i)(?U)(.*['""].*['""\)])(?:\sand\s)|.{1,}?" ; Split And statements inside [] Global $gsBGe_RegExpSplitContains = "(?i)contains\s*\(\s*(.+)\s*,\s*['""](.+)['""]\s*\)" ; Split contains, remove spaces that are not needed Global $gsBGe_RegExpSplitNonContains = "(.*)\s*\=\s*['""](.*)['""]" ; Split constraint that is not a contains, remove spaces that are not needed #endregion GLOBALVariables #region SAMPLE ; Using multiple levels as an example...made comples on purpose to demonstrate...: $xpathForumLink = "//a[contains(@href,'forum')]" $xpathGeneralHelpSuprt = "//a[contains(@href,'autoit-general-help-and-support')]" ; Click the Last page avaiable on the page navigation...which happens to be page 6 $xpathGeneralHelpPagination = "//ul[@class='ipsPagination']/li[last()-3]/a" ; Create/navigate to page $oIE = _IECreate("http://www.autoitscript.com/site/",True,True) If IsObj($oIE) Then ConsoleWrite("Able to _IECreate('http://www.autoitscript.com/site/')" & @CRLF) Else ConsoleWrite("UNable to _IECreate('http://www.autoitscript.com/site/')" & @CRLF) Exit 1 EndIf ; Get Forum Link $aForumLink = BGe_IEGetDOMObjByXPathWithAttributes($oIE,$xpathForumLink) If IsArray($aForumLink) Then ConsoleWrite("Able to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathForumLink & ")" & @CRLF) For $i = 0 To UBound($aForumLink)-1 ConsoleWrite(" " & $aForumLink[$i].outerhtml & @CRLF) Next Else ConsoleWrite("UNable to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathForumLink & ")" & @CRLF) Exit 2 EndIf ; Click the link _IEAction($aForumLink[0], "focus") If _IEAction($aForumLink[0], "click") Then ConsoleWrite("Able to _IEAction($aForumLink[0], 'click')" & @CRLF) _IELoadWait($oIE) Else ConsoleWrite("UNable to _IEAction($aForumLink[0], 'click')" & @CRLF) Exit 3 EndIf ; Get General help link $aGenHelpLink = BGe_IEGetDOMObjByXPathWithAttributes($oIE,$xpathGeneralHelpSuprt) If IsArray($aGenHelpLink) Then ConsoleWrite("Able to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathGeneralHelpSuprt & ")" & @CRLF) For $i = 0 To UBound($aGenHelpLink)-1 ConsoleWrite(" " & $aGenHelpLink[$i].outerhtml & @CRLF) Next Else ConsoleWrite("UNable to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathGeneralHelpSuprt & ")" & @CRLF) Exit 4 EndIf ; Click the link _IEAction($aGenHelpLink[0], "focus") If _IEAction($aGenHelpLink[0], "click") Then ConsoleWrite("Able to _IEAction($aGenHelpLink[0], 'click')" & @CRLF) _IELoadWait($oIE) Else ConsoleWrite("UNable to _IEAction($aGenHelpLink[0], 'click')" & @CRLF) Exit 5 EndIf $aSpecificPageLink = BGe_IEGetDOMObjByXPathWithAttributes($oIE,$xpathGeneralHelpPagination) If IsArray($aSpecificPageLink) Then ConsoleWrite("Able to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathGeneralHelpPagination & ")" & @CRLF) ConsoleWrite(" " & $aSpecificPageLink[0].outerhtml & @CRLF) Else ConsoleWrite("UNable to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathGeneralHelpPagination & ")" & @CRLF) Exit 6 EndIf ; Click the link _IEAction($aSpecificPageLink[0], "focus") If _IEAction($aSpecificPageLink[0], "click") Then ConsoleWrite("Able to _IEAction($aSpecificPageLink[0], 'click')" & @CRLF) _IELoadWait($oIE) Else ConsoleWrite("UNable to _IEAction($aSpecificPageLink[0], 'click')" & @CRLF) Exit 5 EndIf #endregion SAMPLE #region ExternalFunctions Func BGe_IEGetDOMObjByXPathWithAttributes($oIEObject, $sXPath, $iMaxWait=2000) ; Get dom object by XPath If $gbBGe_PerformConsoleWrites Then ConsoleWrite("Start Function=[BGe_IEGetDOMObjByXPathWithAttributes] with $sXPath=[" & $sXPath & "]." & @CRLF) Local $aReturnObjects = "" Local $aSplitXpath = BGe_ParseXPath($sXPath) If Not IsArray($aSplitXpath) Then ConsoleWrite("BGe_IEGetDOMObjByXPathWithAttributes: Callers XPath/Node/Conditions not well formed=[" & $sXPath & "]" & @CRLF) Return SetError(1,0,False) EndIf Local $iTimer = TimerInit() While TimerDiff($iTimer)<$iMaxWait And Not IsArray($aReturnObjects) $aReturnObjects = BGe_RecursiveGetObjWithAttributes($oIEObject,$aSplitXpath) WEnd Return $aReturnObjects EndFunc ;==>BGe_IEGetDOMObjByXPathWithAttributes #endregion ExternalFunctions #region InternalFunctions Func BGe_RecursiveGetObjWithAttributes($oParent, $aCallersSplitXPath, $asHolder="", $Level=0) $asObjects = $asHolder Local $sNodeName = $aCallersSplitXPath[$Level][$giBGe_XPath_Dim2_sNodeName] Local $bNodeIsRelative = $aCallersSplitXPath[$Level][$giBGe_XPath_Dim2_bNodeIsRelative] ; true=relative false=absolute Local $bIsConstrainted = $aCallersSplitXPath[$Level][$giBGe_XPath_Dim2_bIsConstrainted] ; array[OR] of arrays[AND]; all constraints on the node Local $aNodeOrConstraints = $aCallersSplitXPath[$Level][$giBGe_XPath_Dim2_aNodeConstraints] ; array[OR] of arrays[AND]; all constraints on the node Local $iCountToReturnOfCol = $aCallersSplitXPath[$Level][$giBGe_XPath_Dim2_iPredicateReturn] ; 0 returns all nodes; -# returns only last()-#; +# returns only the item whose count is that number in the collection ;~ _ArrayDisplay($aCallersSplitXPath) ; currently only using predicate if present... If $iCountToReturnOfCol <> 0 Then $bIsConstrainted = False EndIf ;~ ConsoleWrite(@CRLF & @CRLF & $iCountToReturnOfCol & @CRLF & @CRLF) Local $aPossibleNodeMatch = "" If $gbBGe_PerformConsoleWrites Then ConsoleWrite("Start Function=[BGe_RecursiveGetObjWithAttributes] level=[" & $Level & "]: $sNodeName=[" & $sNodeName & "], $bNodeIsRelative=[" & $bNodeIsRelative & "] $bIsConstrainted=[" & $bIsConstrainted & "]."& @CRLF) If Not IsObj($oParent) Then Return $asObjects ; Get nodes that match If $bNodeIsRelative Then If $sNodeName = "*" Then $oPossibleNodes = _IETagNameAllGetCollection($oParent) Else $oPossibleNodes = _IETagNameGetCollection($oParent, $sNodeName) EndIf If $iCountToReturnOfCol = 0 Then For $oPossibleNode In $oPossibleNodes If $oPossibleNode.NodeType == 1 Then ; only add nodes If IsArray($aPossibleNodeMatch) Then _ArrayAdd($aPossibleNodeMatch,$oPossibleNode) Else Local $aPossibleNodeMatch[1] = [$oPossibleNode] EndIf EndIf Next Else If $iCountToReturnOfCol > 0 Then ;~ MsgBox(1,1,"a1") Local $iFoundCount = 0 For $oPossibleNode In $oPossibleNodes If $oPossibleNode.NodeType == 1 Then ; only add nodes $iFoundCount+=1 If $iFoundCount <> $iCountToReturnOfCol Then ContinueLoop EndIf ConsoleWrite(@TAB & "found a condition for predicate in a1." & @CRLF) If IsArray($aPossibleNodeMatch) Then _ArrayAdd($aPossibleNodeMatch,$oPossibleNode) Else Local $aPossibleNodeMatch[1] = [$oPossibleNode] EndIf EndIf Next Else ;~ MsgBox(1,1,"a2") If $oPossibleNodes.Length >= Abs($iCountToReturnOfCol) Then ConsoleWrite(@TAB & "found a condition for predicate in a2." & @CRLF) Local $oPossible = $oPossibleNodes.item($oPossibleNodes.Length-$iCountToReturnOfCol) If IsArray($aPossibleNodeMatch) Then _ArrayAdd($aPossibleNodeMatch,$oPossibleNode) Else Local $aPossibleNodeMatch[1] = [$oPossibleNode] EndIf EndIf EndIf EndIf Else $oPossibleNodes = $oParent.childnodes If $iCountToReturnOfCol = 0 Then For $oPossibleNode In $oPossibleNodes If String($oPossibleNode.NodeName) = $sNodeName Or $sNodeName = "*" Then If IsArray($aPossibleNodeMatch) Then _ArrayAdd($aPossibleNodeMatch,$oPossibleNode) Else Local $aPossibleNodeMatch[1] = [$oPossibleNode] EndIf EndIf Next Else If $iCountToReturnOfCol > 0 Then ;~ MsgBox(1,1,"b1") Local $iFoundCount = 0 For $oPossibleNode In $oPossibleNodes If String($oPossibleNode.NodeName) = $sNodeName Or ($sNodeName = "*" And $oPossibleNode.NodeType == 1) Then $iFoundCount+=1 If $iFoundCount <> $iCountToReturnOfCol Then ContinueLoop EndIf ConsoleWrite(@TAB & "found a condition for predicate in b1." & @CRLF) If IsArray($aPossibleNodeMatch) Then _ArrayAdd($aPossibleNodeMatch,$oPossibleNode) Else Local $aPossibleNodeMatch[1] = [$oPossibleNode] EndIf EndIf Next Else ;~ MsgBox(1,1,"b2") Local $aTemp For $oPossibleNode In $oPossibleNodes If String($oPossibleNode.NodeName) = $sNodeName Or ($sNodeName = "*" And $oPossibleNode.NodeType == 1) Then If IsArray($aTemp) Then _ArrayAdd($aTemp,$oPossibleNode) Else Local $aTemp[1] = [$oPossibleNode] EndIf EndIf Next If UBound($aTemp)+$iCountToReturnOfCol >= 0 Then ConsoleWrite(@TAB & "found a condition for predicate in b2." & @CRLF) If IsArray($aPossibleNodeMatch) Then _ArrayAdd($aPossibleNodeMatch,$aTemp[UBound($aTemp)+$iCountToReturnOfCol]) Else Local $aPossibleNodeMatch[1] = [$aTemp[UBound($aTemp)+$iCountToReturnOfCol]] EndIf EndIf EndIf EndIf EndIf ; Loop through nodes against restraints If IsArray($aPossibleNodeMatch) Then For $iChild = 0 To UBound($aPossibleNodeMatch) - 1 Local $oChild = $aPossibleNodeMatch[$iChild] ; Find matching conditions, when necessary If $bIsConstrainted Then ; Loop through OR Conditions For $i = 0 To UBound($aNodeOrConstraints) - 1 Local $aNodeAndConstraints = $aNodeOrConstraints[$i] Local $bAndConditionsMet = True ; Loop through And Conditions, or conditions are outside of this loop, and will go if current and's are not met For $j = 0 To UBound($aNodeAndConstraints) - 1 ; Remove the @... Local $sConstraintName = StringReplace($aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_sNodeName],"@","") Local $bConstraintIsAtt = $aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_bIsAttribute] Local $bConstraintIsNode = $aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_bIsSelf] Local $sConstraintValue = $aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_sNodeValue] Local $bConstraintIsContains= $aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_bIsContains] Local $iReturnItemWithinCol = $aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_iPredicateReturn] If $iReturnItemWithinCol Then ;~ _ArrayDisplay($aNodeAndConstraints) EndIf If $bConstraintIsNode Then If $bConstraintIsContains Then If Not StringInStr(String($oChild.innertext), $sConstraintValue) Then $bAndConditionsMet = False Else If String($oChild.innertext) <> $sConstraintValue Then $bAndConditionsMet = False EndIf ElseIf $bConstraintIsAtt Then Local $sAttributeValue = "" Switch $sConstraintName Case "class" $sAttributeValue = $oChild.className() Case "style" $sAttributeValue = $oChild.style.csstext Case "onclick" $sAttributeValue = $oChild.getAttributeNode($sConstraintName).value Case Else $sAttributeValue = $oChild.getAttribute($sConstraintName) EndSwitch If $bConstraintIsContains Then If Not StringInStr(String($sAttributeValue), $sConstraintValue) Then $bAndConditionsMet = False Else If String($sAttributeValue) <> $sConstraintValue Then $bAndConditionsMet = False EndIf Else ; failure EndIf ; Skip looping if a condition of the And array was not met If Not $bAndConditionsMet Then ExitLoop Next If $bAndConditionsMet Then ; If last level, add the object If $Level = UBound($aCallersSplitXPath) - 1 Then If Not IsArray($asObjects) Then Local $asObjects[1]=[$oChild] Else $bUnique = True ; Only add if not present in the array For $iObject = 0 To UBound($asObjects)-1 If $oChild = $asObjects[$iObject] Then $bUnique=False ExitLoop EndIf Next If $bUnique Then _ArrayAdd($asObjects, $oChild) EndIf Else $asObjects = BGe_RecursiveGetObjWithAttributes($oChild, $aCallersSplitXPath, $asObjects, $Level + 1) EndIf EndIf ; No need to loop additional or if already found one and If $bAndConditionsMet Then ExitLoop Next Else ; No constraints, match is implied If $Level = UBound($aCallersSplitXPath) - 1 Then ; Final xpath level, so add to final array If Not IsArray($asObjects) Then Local $asObjects[1]=[$oChild] Else Local $bUnique=True ; Only add if not present in the array For $iObject = 0 To UBound($asObjects)-1 If $oChild = $asObjects[$iObject] Then $bUnique=False ExitLoop EndIf Next If $bUnique Then _ArrayAdd($asObjects, $oChild) EndIf Else ; Continue Recurssion $asObjects = BGe_RecursiveGetObjWithAttributes($oChild, $aCallersSplitXPath, $asObjects, $Level + 1) EndIf EndIf Next EndIf Return $asObjects EndFunc ;==>BGe_RecursiveGetObjWithAttributes Func BGe_ParseXPath($sCallersXPath) ; RegExp require a trailing "/" $sCallersXPath &= "/" Local $aReturnParsedXPath=False ; Parse all the '/' outside of single, or double, quotes Local $aNodesWithQualifiers = StringRegExp($sCallersXPath,$gsBGe_RegExpNodeSplit,3) ; Loop through, and determine if the node is direct, or relative.../ vs // Local $iSlashCount = 0 For $i = 0 To UBound($aNodesWithQualifiers) - 1 If StringLen($aNodesWithQualifiers[$i])=0 Then $iSlashCount+=1 Else Local $iLastNodeReturn = 0 ; Add dimentions to the return array If Not IsArray($aReturnParsedXPath) Then Local $aReturnParsedXPath[1][$giBGe_XPath_Dim2_UBound] Else ReDim $aReturnParsedXPath[UBound($aReturnParsedXPath)+1][$giBGe_XPath_Dim2_UBound] EndIf $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_sRawNode] = $aNodesWithQualifiers[$i] ; Split current Node Local $aSplitNodeAndCond = StringRegExp($aNodesWithQualifiers[$i],$gsBGe_RegExpNodeAndCondSplit,3) If UBound($aSplitNodeAndCond) = 2 Then Local $sNodeName = $aSplitNodeAndCond[0] Local $sNodeConstraints = $aSplitNodeAndCond[1] ; check if last() or just a number... If StringLeft($sNodeConstraints,6) = "last()" Then $iLastNodeReturn = -1 Local $iLastLessCount = Number(StringRegExpReplace($sNodeConstraints,"(last\(\)\-)(\d+)","$2")) $iLastNodeReturn -= $iLastLessCount ElseIf Number($sNodeConstraints) Then $iLastNodeReturn = Number($sNodeConstraints) Else $aNodeConstraints = BGe_ParseXPathConstraints($sNodeConstraints) If Not IsArray($aNodeConstraints) Then ConsoleWrite("ParseXPath: Callers XPath/Node/Conditions not well formed=[" & $aNodesWithQualifiers[$i] & "]" & @CRLF) Return SetError(1,1,False) EndIf EndIf ElseIf UBound($aSplitNodeAndCond) = 0 Then Local $sNodeName = $aNodesWithQualifiers[$i] Local $sNodeConstraints = "" Local $aNodeConstraints = "" Else ConsoleWrite("ParseXPath: Callers XPath/Node/Conditions not well formed=[" & $aNodesWithQualifiers[$i] & "]" & @CRLF) Return SetError(1,2,False) EndIf $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_sNodeName] = $sNodeName $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_sRawNodeConstraints] = $sNodeConstraints $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_bIsConstrainted] = (StringLen($sNodeConstraints)>0) $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_aNodeConstraints] = $aNodeConstraints $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_bNodeIsRelative] = $iSlashCount>1 $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_iPredicateReturn] = $iLastNodeReturn ;~ _ArrayDisplay($aReturnParsedXPath) $iSlashCount=1 EndIf Next Return $aReturnParsedXPath EndFunc Func BGe_ParseXPathConstraints($sCallersXPathConstraints) ; Returns array of arrays ; Array is split of all 'or' statements, and then includes array of 'and' statements, which are split out into 2d array of name/value/bcontains Local $aReturnParsedXPathConstraints[1] ; Will always return at least the first condition ConsoleWrite($sCallersXPathConstraints & @CRLF) Local $aOrQualifiers = StringRegExp($sCallersXPathConstraints,$gsBGe_RegExpOrSplit,3) ReDim $aReturnParsedXPathConstraints[UBound($aOrQualifiers)] For $i = 0 To UBound($aReturnParsedXPathConstraints)-1 Local $aAndQualifiers = StringRegExp($aOrQualifiers[$i],$gsBGe_RegExpAndSplit,3) Local $aaSplitQualitfiers = BGe_ParseXPathConstraint($aAndQualifiers) If IsArray($aaSplitQualitfiers) Then $aReturnParsedXPathConstraints[$i]=$aaSplitQualitfiers Else ConsoleWrite("ParseXPathConstraints: Callers XPath/Node/Conditions not well formed=[" & $aOrQualifiers[$i] & "]" & @CRLF) Return SetError(1,3,False) EndIf Next Return $aReturnParsedXPathConstraints EndFunc Func BGe_ParseXPathConstraint($aCallersXPathConstraint) Local $aReturnParsedXPathConstraints[UBound($aCallersXPathConstraint)][$giBGe_Constraint_Dim2_UBound] For $i = 0 To UBound($aCallersXPathConstraint)-1 Local $iLastNodeReturn = 0 ; Remove leading and trailing spaces Local $sCurrentConstraint = StringStripWS($aCallersXPathConstraint[$i], 3) ; Check if $sCurrentConstraint makes use of contains() Local $aTempContains = StringRegExp($sCurrentConstraint,$gsBGe_RegExpSplitContains,3) Local $aTempNonContains = StringRegExp($sCurrentConstraint,$gsBGe_RegExpSplitNonContains,3) ;~ _ArrayDisplay($aTempContains,"contains") ;~ _ArrayDisplay($aTempNonContains,"noncontains") If UBound($aTempContains)=2 Then $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsContains] = True $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsSelf] = ($aTempContains[0]=".") $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeName] = $aTempContains[0] $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsAttribute] = (StringLeft($aTempContains[0],1)="@") $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeValue] = $aTempContains[1] $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_iPredicateReturn] = $iLastNodeReturn ElseIf Number($sCurrentConstraint) Then ; check if count is present...if so, then that is the only constraint $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsContains] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsSelf] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeName] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsAttribute] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeValue] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_iPredicateReturn] = Number($sCurrentConstraint) ElseIf StringLeft($sCurrentConstraint,"6") = "last()" Then ; ; check if use of last() is present...if so, return the last item in the collection...allow use of last()-1 to return the second to last item $iLastNodeReturn = -1 Local $aLastLessCount = Number(StringRegExpReplace($sCurrentConstraint,"(last\(\)\-)(\d+)","$2")) $iLastNodeReturn -= $aLastLessCount $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsContains] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsSelf] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeName] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsAttribute] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeValue] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_iPredicateReturn] = $iLastNodeReturn ElseIf UBound($aTempNonContains)=2 And Not StringInStr($aTempNonContains[0],"(") Then $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsContains] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsSelf] = ($aTempNonContains[0]=".") $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeName] = $aTempNonContains[0] $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsAttribute] = (StringLeft($aTempNonContains[0],1)="@") $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeValue] = $aTempNonContains[1] $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_iPredicateReturn] = $iLastNodeReturn ;~ ElseIf Number($sCurrentConstraint) Then ;~ ; ; check if only a specific item in collection is to be returned...'[2]' would return the second matching item ;~ $iLastNodeReturn = Number($sCurrentConstraint) ;~ MsgBox(1,1,1) Else ConsoleWrite("ParseXPathConstraint: Callers XPath/Node/Conditions not well formed=[" & $aCallersXPathConstraint[$i] & "]" & @CRLF) Return SetError(1,4,False) EndIf Next Return $aReturnParsedXPathConstraints EndFunc #endregion InternalFunctions Edited August 13, 2015 by jdelaney IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.
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