Retrieve the value of a XML attribute in VBS - vbscript

<Requirement Description="description" Operation="Configure">
<Action ID="1000" Name="Split">
<Contract>
<Parameter Name="Version">4</Parameter>
<Parameter Name="DefaultServer">192.168.00.</Parameter>
<Parameter Name="DefaultUser">administrator</Parameter>
<Parameter Name="DefaultPassword">password</Parameter>
<Parameter Name="DefaultDomain">192.168.00.00</Parameter>
<Parameter Name="Split">1</Parameter>
</Contract>
</Action>
</Requirement>
From the above XML document my aim is to replace the IP address for both the attributes default server and default domain from a VBScript.
Set objXMLDoc = CreateObject("Microsoft.XMLDOM")
objXMLDoc.async = False
objXMLDoc.load(XMLFullPath)
Set NodeList = objXMLDoc.documentElement.SelectNodes("//Parameter")
NodeList(i).nodeName
Give name as Parameter and NodeList(i).Text gives me values like 4, IP address, administrator and others. But I am not able to get the attribute name so that I can directly change the value of the attribute.

To answer your question, you can use the getAttribute function to access an attribute's value:
NodeList(i).getAttribute("Name")
You can also add a predicate to the XPath expression in your SelectNodes call to retrieve only the desired elements:
Set NodeList = objXMLDoc.documentElement.SelectNodes("//Parameter[#Name = 'DefaultServer' or #Name = 'DefaultDomain']")
This way, you don't have to retrieve and loop through the Parameter nodes that you're not interested in.

A bit rusty, but I think you can use this to retrieve the nodevalue by nodename:
Function getTag(nList, nName)
Dim i
i = 0
Do while i < nList.childNodes.length
if (nList.childNodes(i).nodeName = nName) then
getTag = nList.childNodes(i).childNodes(0).text
Exit Function
end if
i = i + 1
Loop
End Function
And to set it, probably
Sub setTag(nList, nName, val)
Dim i
i = 0
Do while i < nList.childNodes.length
if (nList.childNodes(i).nodeName = nName) then
nList.childNodes(i).childNodes(0).text = val
Exit Sub
end if
i = i + 1
Loop
End Sub

Related

How do I reach the second child node of an element XML in vbscript?

After spending many hours on the internet I was not able to get this to work and need some help.
XML:
xml snippet highlighting NoteSynopsis
CODE:
set xmlDoc = SERVER.CREATEOBJECT("MSXML2.DomDocument.6.0")
xmlDoc.async = False xmlDoc.Load("D:\GVPApplications\TechSupportCreateIncident\CreateIncidentRequest.xml")
xmlDoc.setProperty "NewParser","true"
set Root = xmlDoc.documentElement
set NodeList1 = Root.getElementsByTagName("IncidentNote")
For Each Elem in NodeList1
if Elem.firstChild.nodename = "Note" then
Elem.firstChild.text = Notes
end if
Next
ISSUE:
As highlighted in the image XML , I need to be able to read "NoteSynopsis" element and its value. As simple as this seems I have not been able to find a solution to this. If this was the last child no issue, I would do a Elem.LastChild.nodename, but this isn't!
You could use the selectSingleNode(...) method and use XPath
set xmlDoc = SERVER.CREATEOBJECT("MSXML2.DomDocument.6.0")
xmlDoc.async = False xmlDoc.Load("D:\GVPApplications\TechSupportCreateIncident\CreateIncidentRequest.xml")
xmlDoc.setProperty "NewParser","true"
xmlDocument.setProperty "SelectionLanguage", "XPath"
Dim firstIncidentNote
set firstIncidentNote = xmlDoc.SelectSingleNode("//IncidentNote")
Dim note
Dim noteSynopsis
set note = firstIncidentNote.GetAttribute("Note")
set note = firstIncidentNote.GetAttribute("NoteSynopsis")
https://msdn.microsoft.com/en-us/library/ms757846(v=vs.85).aspx

Convert vbscript into rapid integration flowlanguage

I'm using Pervasive 9.2 and would like to somehow convert the vbscript into pervasives RIFL language. I want to execute the code during a Process where the f(x) component is executed to run the code. As far as the Path to the xml data, I'll be using a Macro defining where the source data is and another to save the file as well.
Here is the vbscript code below:
Set xml = CreateObject("Microsoft.XMLDOM")
xml.async = False
count_var = 1
If xml.Load("c:\folder1\test.xml") Then
For Each accounts In xml.SelectNodes("//Accounts")
For Each account In Accounts.SelectNodes("./Account")
If count_var > 1 Then
Set accountEnum = xml.createNode(1, "Account" & count_var, "")
For Each child In Account.childNodes
accountEnum.appendChild(child.cloneNode(TRUE))
Next
Accounts.replaceChild accountEnum, Account
xml.save("c:\folder1\test.xml")
else
Set accountEnum = xml.createNode(1, "Account" & count_var, "")
For Each child In Account.childNodes
accountEnum.appendChild(child.cloneNode(TRUE))
Next
Accounts.replaceChild accountEnum, Account
xml.save("c:\folder1\test.xml")
End If
count_var = count_var + 1
Next
count_var = 1
Next
End If
Set node = Nothing
Set xml = Nothing
ParseXMLFile(filepath)
documentation here
http://docs.pervasive.com/products/integration/di/rifl/wwhelp/wwhimpl/common/html/wwhelp.htm#href=ParseXMLFile_Function.html&single=true
this will return a DOMDocument Object Type
documentation here
http://docs.pervasive.com/products/integration/di/rifl/wwhelp/wwhimpl/common/html/wwhelp.htm#href=DOMDocument_Object_Type.html&single=true
hope this helps

Changing node values in XML using VBS with similar names

I am facing this challenge with changing values of nodes in an xml file which has same names, using VBScript. Following is the sample XML:
- <MappingData>
<Name>Name 1</Name>
- <ValueField FieldName="Name 2">
<CharValue>Value 1</CharValue>
</ValueField>
- <ValueField FieldName="Name 3">
<CharValue>Value 1</CharValue>
</ValueField>
My requirement is to change the values of both occurrences of tag
<CharValue>
.
I could have done this if there was any attribute in these tags, but in this case I am stuck.
I tried the following code, but could'nt get what I need.
Set NodeList = objXMLDoc.documentElement.selectNodes("//MappingData/ValueField/CharValue")
For i = 0 To NodeList.length - 1
node.Text = "Value 1"
Next
Any help is appreciated. Thanks.
Try the following code
Set xDoc = CreateObject( "Msxml2.DOMDocument.6.0" )
xDoc.setProperty "SelectionLanguage", "XPath"
xDoc.async = False
xDoc.load "test.xml"
Set nNodes = xDoc.selectNodes("//MappingData/ValueField/CharValue")
For i = 0 To nNodes.Length - 1
nNodes(i).text = "Changed value " & i
Next
xDoc.Save "test.xml"

Object doesn't support this property or method: 'xmldoc2.importNode'

I am trying to copy nodes from one XML document into another.
Project is a root element inboth documents and I want to select all ItemGroup elements from first document and insert them before Import element in the second document. Unfortunately, I get
Object doesn't support this property or method: 'xmldoc2.importNode'
Here is the code I am using:
Set xmldoc1 = CreateObject("Microsoft.XMLDOM")
xmldoc1.async = false
xmldoc1.load WScript.Arguments(0)
Set xmldoc2 = CreateObject("Microsoft.XMLDOM")
xmldoc2.async = false
xmldoc2.load WScript.Arguments(1)
Set importNode = xmldoc2.selectSingleNode("//Project/Import")
Set nodes = xmldoc1.selectNodes("//Project/ItemGroup")
For Each node In nodes
Set newNode = xmldoc2.importNode(node, True)
xmldoc2.insertBefore newNode, importNode
Next
How should I fix the code?
EDIT:
Thanks to #Ekkehard.Horner, I solved the issue. Here is the updated code
Set xmldoc1 = CreateObject("Microsoft.XMLDOM")
xmldoc1.async = false
xmldoc1.load WScript.Arguments(0)
Set xmldoc2 = CreateObject("Microsoft.XMLDOM")
xmldoc2.async = false
xmldoc2.load WScript.Arguments(1)
Set importNode = xmldoc2.selectSingleNode("//Project/Import")
Set nodes = xmldoc1.selectNodes("//Project/ItemGroup")
For Each node In nodes
Set newNode = node.cloneNode(true)
xmldoc2.documentElement.insertBefore newNode, importNode
Next
The docs for importNode state:
[This sample code uses features that were first implemented in MSXML
5.0 for Microsoft Office Applications.]
I'd try to use
"Msxml2.DOMDocument" or "Msxml2.DOMDocument.6.0" instead of "Microsoft.XMLDOM"
.cloneNode instead of .importNode

How can I strip the element using vbscript and display in message box?

I would like to find the price with 2 year contract and display it in a message box. Sofar I have:
Dim MyPage
Dim Price
Set MyPage=CreateObject("Microsoft.XMLDOM")
MyPage.load("http://www.verizonwireless.com/b2c/store/controller?item=phoneFirst&action=viewPhoneDetail&selectedPhoneId=5723")
Wscript.Sleep 2000
Set Price = MyPage.getElementsByTagName("span")
For Each Elem In Price
MsgBox(Elem.firstChild.nodeValue)
Next
I understand that I am completely wrong, but I don't even know where to start. I love writing simple programs like this, but I just need help getting started. Any ideas will help!
Here a better version, uses the HTMLFile object
Dim HTMLDoc, XML, URL, table
Set HTMLDoc = CreateObject("HTMLFile")
Set XML = CreateObject("MSXML2.XMLHTTP")
URL = "http://www.verizonwireless.com/b2c/store/controller?item=phoneFirst&action=viewPhoneDetail&selectedPhoneId=5723"
With XML
.Open "GET", URL, False
.Send
HTMLDoc.Write .responseText
End With
Set spans = HTMLDoc.getElementsByTagName("span")
for each span in spans
WScript.Echo span.innerHTML
next
'=><SPAN>Set Location</SPAN>
'=>Set Location
'=><SPAN>Submit</SPAN>
'=>Submit
'=>Connect with us
the control you use is for reading XML documents, you need something like this
'Create an xmlhttp object, the string depends on the version that is installed
'on your pc could eg also be "Msxml2.ServerXMLHTTP.5.0"
Set xmlhttp = CreateObject("Microsoft.XMLHTTP")
xmlhttp.Open "GET", "http://admin:pasword#10.0.0.2/doc/ppp.htm", False
xmlhttp.Send
text=xmlhttp.responseText
wscript.echo text
Set xmlhttp = Nothing
Run a search in your registry for XMLHTTP to get the right string/version for the identifier.
To get the tag from the html you can use the following
text = "blabla <span>this is what i need</span> bla bla<span>second item</span> end"
function getElementsByTagName(sTextToSeachIn, tag)
answer = ""
separator = ""
set oRegExpre = new RegExp
with oRegExpre
.IgnoreCase = true
.Global = true
.MultiLine = True
.Pattern = "<" & tag & ">(.*?)</" & tag & ">"
end with
set oColMatches = oRegExpre.Execute(sTextToSeachIn)
for each match in oColMatches
answer = answer & separator & match.subMatches(0)
separator = "|" 'use something that's not in the spancontents
next
if separator <> "" then
getElementsByTagName = split(answer, separator)
else
getElementsByTagName = array()
end if
end function
for each tag in getElementsByTagName(text, "span")
wscript.echo tag
next
'=>this is what i need
'=>second item
There are better techniques and certainly better languages than vbscript to do this, i suggest to take a look at Ruby which exels in such things.
Alex, in response to your comment about getting a cookie and running a javascript in HTMLFile, here a ruby script i found, hopes it helps you at some point, it reads in a page, passes it to the HTLMFile object and in that DOM executes a remote javascript file. It also gives you an idea of the combined power of activeX and Ruby.
require "win32ole"
$jsxpath_uri = "http://svn.coderepos.org/share/lang/javascript/javascript-xpath/trunk/release/javascript-xpath-latest-cmp.js"
uri, xpath = "http://gist.github.com/gists", "//div[#class='info']/span/a"
http = WIN32OLE.new('MSXML2.XMLHTTP')
http.Open "GET", uri, false
http.Send
text = http.responseText
dom = WIN32OLE.new("htmlfile")
dom.Write(text)
dom.parentWindow.eval(open($jsxpath_uri){|f| f.read })
items = dom.evaluate(xpath, dom, nil, 7, nil)
len = items.snapshotLength
(0...len).each do |i|
item = items.snapshotItem(i)
puts item.innerHTML
end

Resources