I am trying to query an XML File in order to get the attribute values for a specific element.
This works fine when the element has a unique set of attribute e.g.
<parent>
<child code="REWC" curr="PLN" amt="1000"/>
</parent>
In order to query the above I use:
object = Microsoft.XMLDOM
getElementsByTagName OR selectSingleNode method
Once I have that, I run the 'getAttribute' method, which gives me what I need
code snippet:
Set ElementValue = m_objXmlDom.selectSingleNode("//Txn[" & p_intIndex & "]/" & p_strElementName & " ")
'set attribute value
strAttributeValue = ElementValue.getAttribute(p_strAttributeName)
However, I am now in a situation where the XML looks as per below:
<parent>
<child code="REWC" curr="PLN" amt="1000"/>
<child code="xxxx" curr="EUR" amt="1500"/>
<child code="yyyy" curr="GBP" amt="1700"/>
</parent>
Is there a simple way to iterate through each attribute, get the value, and then I can do something with it.
I am looking for something like:
.getAttribute(code)[0]
.getAttribute(code)[1]
.getAttribute(code)[2]
Something like the above will print out all the values for all attributes. But Im not to sure how to index at the attribute level.
Any help would be great. I am using VBScript with Microsoft XMLDom.
Ok, I have gotten around the issue now by doing a for loop in order to iterate
over all of the elements that have been returned, and then reading in each attribute.
If the attribute matches the one I am looking for then I exit the for loop.
if there is a better way of doing this, then please share any answers, in the meantime my
code is working as per below.
Code snippet:
Set Data = m_objXmlDom.getElementsByTagName(".//Txn[" & p_intIndex & "]/" & p_strElementName & "/" & p_strSubElementName & "")
'loop through each one
For Each DataItem in Data
strTemp1 = DataItem.getAttribute("code")
strTemp2 = DataItem.getAttribute("curr")
strTemp3 = DataItem.getAttribute("amt")
If strTemp1 = strExpectedValue Then
'set the values
m_strTemp1 = strTemp1
m_strTemp2 = strTemp2
m_strTemp3 = strTemp3
'set pass flag
blnDataFound = True
Exit For
End If
Next
Related
Please excuse me if this question is dumb.
I need to get an input value and pass it in a POST parameter like follow:
SQL = "[proc_Happy]" & Request.Cookies("UserID")& "," & Request.Form("MYINPUTFIELD")
I have tried hardcoding MYINPUTFIELD with (it worked!):
SQL = "[proc_Happy]" & Request.Cookies("UserID")& "," & 54555152
My input in the asp page looks as follow:
<input type="number" name="MYINPUTFIELD " id="MYINPUTFIELD" value="<%=MYINPUTFIELD%>">
Things I have tried:
Getting the value with JS - failed.
Notes:
MYINPUTFIELD is an int
Is your input field in a form, i.e. is it between <form...> and </form> tags? If no, that's your problem right there. If yes, what does the <form...> tag have in it? Does it say method='get'? If yes, then your inputs are being put in the querystring, not the form object. For Request.Form(...) to work, your form needs to say method='post'.
If you need this code to work with both form methods, you can do something like
dim MyInputField
MyInputField = Request.Querystring("MyInputField")
If MyInputField = "" Then MyInputField = Request.Form("MyInputField")
'make the "OMGSQLINJECTION!!1!" people just go away already
'(note to such people: he's using a frigging stored procedure.)
If Not Isnumeric(MyInputField) Then
MyInputField = 0
End If
SQL = "[proc_Happy]" & Request.Cookies("UserID")& "," & MyInputField
I am comparatively new to UFT as well as VB script.
I am trying to check innertext of divs inside For loop.
set getData = Browser("Browser").Page("Page").Object.getElementsByClassName("ClassName")
'Below line outputs 5'
msgbox getData.length-1
'output innertext for all these divs'
For i=0 to getData.length-1
msgbox getData(i).innertext
Next
This gives me Object Required Error on this line
msgbox getData(i).innertext
My first and 2nd element is blank while 3,4,5 are non-empty values.
When I write
msgbox getData(0).innertext
msgbox getData(1).innertext
msgbox getData(2).innertext
It gives me proper results
I further need to check this data against "Data" spreadsheet in UFT
Any pointers would be very much helpful.
Thanks,
Clarification needed:
As you would like to query div text, Is that any reason to use ClassName? If that so, you could use getElementsbyTagName instead getElementsByClassName.
However, I enhanced the code and adapting the query by any tag name option in the function. Here you go.
Dim objResultsDictionary
Set objResultsDictionary = GetTextContentFromHtmlTag(Browser("title:=Welcome: Mercury Tours").Page("title:=.*"),"div","")
Msgbox objResultsDictionary.Count
Result:8
Set objResultsDictionary = GetTextContentFromHtmlTag(Browser("title:=Welcome: Mercury Tours").Page("title:=.*"),"ClassName","mouseOut")
Msgbox objResultsDictionary.Count
Result = 11
Public Function GetTextContentFromHtmlTag(ByVal BrowserObject,ByVal TagName,ByVal TagValue)
Dim objDictionary
Dim objCollection
Set objDictionary = CreateObject("Scripting.Dictionary")
Select Case UCase(TagName)
Case "DIV"
Set objCollection = BrowserObject.Object.getElementsByTagName(TagName)
Case "CLASSNAME"
Set objCollection = BrowserObject.Object.getElementsByClassName(TagValue)
End Select
intDivCount = objCollection.Length
If intDivCount > 0 Then
For intCounter = 0 To intDivCount
If IsObject(objCollection(intCounter)) Then
strTagInnerText = objCollection(intCounter).innerText
If strTagInnerText <> "" Then
objDictionary.Add intCounter,strTagInnerText
End If
End If
Next
End If
Set GetTextContentFromHtmlTag = objDictionary
End Function
What you have to do:
You have to iterate the dictionary and get the innertext of the each tag.
Its giving you that error most probably because, there is various elements with the same class name other than the div or divs.
Try using some other properties.
I need to compare 2 xml files using QTP where the values for each tag needs to be compared and need to print the difference in values if found. I used the built in Function XMLUTIL but its not working as expected i.e.. its creates a file with differences including the parent tag.
<tns:AAL_Request_NEW xsi:schemaLocation="http://www.bnymellon.com/AAL_Request_NEW AAL_Request_NEW.xsd">
<tns:OPF_Information>
<tns:Source>
<tns:Source>EPH</tns:Source>
</tns:Source>
<tns:References>
<tns:Accounting_Record_Reference>130830000672401</tns:Accounting_Record_Reference>
<tns:OPF_Reference>EPH1308300006724</tns:OPF_Reference>
<tns:Group_Reference>EPH1308300006723</tns:Group_Reference>
</tns:References>
</tns:OPF_Information>
</tns:AAL_Request_NEW>
In the above xml file i just need the tags with values like
tns:Source with value EPH, tns:Accounting_Record_Reference with value 130830000672401, tns:OPF_Reference with value EPH1308300006724 and tns:Group_Reference EPH1308300006723 to be compared and not the parent tags like tns:References, tns:OPF_Information or tns:AAL_Request_NEW.
Can anyone help with the logic to fetch the tags which has no child tag inside it and ends immediately with having only a value between its start <> and end and compare it with the other file and print the tag name and the values if there is a difference?
you can use CreateObject("Microsoft.XMLDOM") to read the xml files and retrive the tags by tag name and comparte them both.
Set objXMLDoc = CreateObject("Microsoft.XMLDOM")
objXMLDoc.async = False
objXMLDoc.load("<XML PATH>")
Set Root = objXMLDoc.documentElement
Set tags = root.tagnames
Set NodeList = Root.getElementsByTagname("<node name>")
For Each Elem In NodeList
msgbox Elem.text
Next
Thanks and regards
I'm having problems building a collection of data. The problem code is as follows:
'Basic defitions are as follows:
Private mCol As Collection
Dim mcnn As ADODB.Connection
Dim mrs As New ADODB.Recordset
Dim uCustomClass As CustomClass
On Error GoTo 0
'set Find to false to catch any errors
Find = False
'checks for an active connection and then..
Set mCol = Nothing
Set mCol = New Collection
With mrs
.Open AN_SQL_SELECT_STATEMENT , mcnn, adOpenForwardOnly, adLockOptimistic
While Not .EOF
Set uCustomClass = New CustomClass
Set uCustomClass.Connection = mcnn
uCustomClass.CustomerName = NullToEquiv(.Fields("customer_name").Value,NULL_STRING)
uCustomClass.NumberOfOrders = NullToEquiv(.Fields("num_of_orders").Value, NULL_LONG)
uCustomClass.FavoriteColour = NullToEquiv(.Fields("favorite_colour").Value, NULL_STRING)
'Cache orginal values in case the keys change
uCustomClass.CacheOriginalValues
'add to collection
mCol.Add uCustomClass
.MoveNext
Wend
Now the result of this in run time is that the uCustomClass tree structure looks like:
-uCustomClass
+connection
count
+ mcnn
-mCol
+Item1
+Item2
+Item3
+mrs
mvarChangedCount
+NewEnum
It's all good bar I'm not getting Item1, Item2 and Item3 directly under the uCustomClass but only in mCol. I've what appears to be the exact same code running elsewhere for a different custom class and I'm getting what I want e.g.
-uCustomClassThatWorks
+connection
count
+ mcnn
-mCol
+Item1
+Item2
+Item3
+mrs
mvarChangedCount
+NewEnum
+Item1
+Item2
+Item3
Any ideas where the problem might be?
Not sure how uCustomClass would ever get those items added. Is there some missing code or something?
One point worth making is that collections can't have the same keys more than once, which would explain why they are able to be added in one area, but not able to be added again. There might be something that is even trimming strings or something that would aggravate the situation. So just make sure your keys are unique.
What XPath query should I use to get to the GetLogisticsOfferDateResult Node?
I have attached the vbscript that I'm using.
I suspect the problem has to do with the multiple namespaces in the document. But how do I reference the second namespace in the XPath?
Dim responseXML
responseXML = '"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/""><s:Body><GetLogisticsOfferDateResponse xmlns=""http://schneider-electric.com/OrderEntryService""><GetLogisticsOfferDateResult>2010-07-20</GetLogisticsOfferDateResult></GetLogisticsOfferDateResponse></s:Body></s:Envelope>"'
Dim responseDoc
Set responseDoc = WScript.CreateObject("MSXML2.DOMDocument.6.0")
responseDoc.loadXML(responseXML)
responseDoc.setProperty "SelectionNamespaces", "xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'"
Dim requestedNode
'This node is not found
'Set requestedNode = responseDoc.selectSingleNode("//s:Envelope//s:Body//GetLogisticsOfferDateResponse//GetLogisticsOfferDateResult")
'This node is found
Set requestedNode = responseDoc.selectSingleNode("//s:Envelope//s:Body")
'This node is found
'Set requestedNode = responseDoc.selectSingleNode("//s:Envelope")
If requestedNode Is Nothing Then
WScript.Echo "Node not found"
Else
WScript.Echo requestedNode.text
End If
Set responseDoc = Nothing
Set LODateNode = Nothing
Turns out my setting of selectionNamespaces had to be as follows:
responseDoc.setProperty "SelectionNamespaces", "xmlns:sc='http://schneider-electric.com/OrderEntryService' xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'"
Then the XPath query had to be:
Set requestedNode = responseDoc.selectSingleNode("//s:Envelope//s:Body//sc:GetLogisticsOfferDateResponse//sc:GetLogisticsOfferDateResult")
You have not defined the default namespace of the document (http://schneider-electric.com/OrderEntryService) in your code.
responseDoc.setProperty "SelectionNamespaces", "'http://schemas.xmlsoap.org/soap/envelope/' 'http://schneider-electric.com/OrderEntryService'"
You will either need to add it, or prefix the elements that belong to it with it.