VBScript Converting XML Data to an ADODB RecordSet - vbscript

I have a situation in which I need to dump XML into an ADODB Recordset in VBScript. My XML is in the form below. What I would like to do in my code is convert the XML into a recordset with AddressObject rows. The code below I tried but keep running into one DomDocument error after another. Can anyone please help me with a solution for this? I tried the code below in Notepad++ but still unable to get the right result.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<AuthorizationToken xmlns="http://www.avectra.com/2005/">
<Token>8d92d5ba-8b06-4464-9829-86eacac68e6c</Token>
</AuthorizationToken>
</soap:Header>
<soap:Body>
<GetQueryResponse xmlns="http://www.avectra.com/2005/">
<GetQueryResult>
<AddressObjects xsi:schemaLocation="http://www.avectra.com/2005/ Address.xsd" recordReturn="1">
<AddressObject>
<adr_key>2bbcd09f-89c7-4558-93bb-ce23e832ab94</adr_key>
<adr_line1>1447 Limerick Lane</adr_line1>
<adr_line2 xsi:nil="true" />
<adr_line3 xsi:nil="true" />
<adr_city>Canyon Lake</adr_city>
<adr_state>TX</adr_state>
<adr_post_code>78133</adr_post_code>
<adr_city_state_code>Canyon Lake, TX 78133</adr_city_state_code>
<adr_country>UNITED STATES</adr_country>
<adr_intl_province xsi:nil="true" />
<adr_county>Comal</adr_county>
<adr_bad_address_flag>0</adr_bad_address_flag>
<adr_no_validation_flag>0</adr_no_validation_flag>
<cst_id>001049008I</cst_id>
</AddressObject>
</AddressObjects>
</GetQueryResult>
</GetQueryResponse>
</soap:Body>
</soap:Envelope>
Public Function XMLToRecSet(Byref objXMLDoc2)
Dim rsReturn
Dim node
Dim attr ,attrs
Dim ObjXmlDoc
Set ObjXmlDoc = CreateObject("MSXML2.DOMDocument.3.0")
'Create/open the disconnected recordset
ObjXmlDoc = objXMLDoc2
Set node = objXMLDoc.selectSingleNode("//AddressObject/")
If( Not node Is Nothing) Then
Set rsReturn = CreateObject("ADODB.Recordset.6.0")
Set attrs = node.getAttributes()
for Each attr In attrs
rsReturn.Fields.Append attr.nodeName, adVarWChar, 255
Next
rsReturn.CursorLocation = adUseClient
rsReturn.CursorType = adOpenStatic
rsReturn.LockType = adLockOptimistic
rsReturn.Open
Set node = Nothing
'Loop/add rows
For Each node In objXMLDoc.selectNodes("//AddressObject/")
rsReturn.AddNew
For Each attr In node.Attributes
If(Not rsReturn(attr.nodeName)Is NOTHING) Then
rsReturn(attr.nodeName) = 1'attr.nodeValue
End if
Next
Next
If rsReturn.RecordCount <> 0 Then rsReturn.MoveFirst
'cExit:
End If
'Dispose DOM document
Set objXMLDoc = Nothing
Set XMLToRecSet = rsReturn
Set rsReturn = Nothing
End Function

Ado cannot handle an xml recordset. I think you need to use the old XML parser to get the data out. You could throw it into a db and then use ado to manipulate the data once its in a database.
Classic asp makes it very hard to work with Soap web services. I would strongly suggest coding this portion of your application in ASP.net ..

Related

add xml as a child node in exsiting xml using vb6

I have existing xml and trying to add an new xml as a child node.but it converting child xml in weird format.Child xml's all the tag < converted as &lt and all /> converted in &gt
I am using this vb code
objAdjoin.appendChild .createElement("DOCCHKLIST")
objAdjoin.selectSingleNode("DOCCHKLIST").appendChild .createTextNode(DocCheckListXML)
Child XML :
<DOCCHKLIST><DOCCHK><CDSEQGER>800</CDSEQGER><RLOSDOCSEQNO>MCV3453</RLOSDOCSEQNO><CLSEQNO>1</CLSEQNO></DOCCHK><DOCCHK><CDSEQGER>801</CDSEQGER><RLOSDOCSEQNO>MCV3453</RLOSDOCSEQNO><CLSEQNO>1</CLSEQNO></DOCCHK></DOCCHKLIST>
Output :
<Message><Output><AANO>MMG050069</AANO><LOADSCLSEQ>MMG050069</LOADSCLSEQ><RLOSCOLLSEQNO>SKE050003</RLOSCOLLSEQNO><CLCHKLSTTYPE>ASNB/UTRS</CLCHKLSTTYPE><DOCCHKLIST><DOCCHK><CDSEQGER>800</CDSEQGER><RLOSDOCSEQNO>MCV3453</RLOSDOCSEQNO><CLSEQNO>1</CLSEQNO></DOCCHK><DOCCHK><CDSEQGER>801</CDSEQGER><RLOSDOCSEQNO>MCV3453</RLOSDOCSEQNO><CLSEQNO>1</CLSEQNO></DOCCHK></DOCCHKLIST><Status>00</Status><ErrorMessage>Processing Complete</ErrorMessage></Output></Message>
Without adding the child nodes individually I have managed to get it to work as follows:
Private Sub Command_Click()
Dim objDomDoc As DOMDocument60
Dim objDom1 As DOMDocument60
Dim strParent As String
Dim strChild As String
Dim objAdJoin As IXMLDOMElement
strParent = "<Message><Output><AANO>MMG050069</AANO><LOADSCLSEQ>MMG050069</LOADSCLSEQ><RLOSCOLLSEQNO>SKE050003</RLOSCOLLSEQNO><CLCHKLSTTYPE>ASNB/UTRS</CLCHKLSTTYPE></Output></Message>"
strChild = "<DOCCHKLIST><DOCCHK><CDSEQGER>800</CDSEQGER><RLOSDOCSEQNO>MCV3453</RLOSDOCSEQNO><CLSEQNO>1</CLSEQNO></DOCCHK><DOCCHK><CDSEQGER>801</CDSEQGER><RLOSDOCSEQNO>MCV3453</RLOSDOCSEQNO><CLSEQNO>1</CLSEQNO></DOCCHK></DOCCHKLIST>"
Set objDomDoc = New DOMDocument60
Set objDom1 = New DOMDocument60
objDomDoc.loadXML (strParent)
objDom1.loadXML strChild
Set objAdJoin = objDomDoc.firstChild
objAdJoin.appendChild objDomDoc.createElement("DOCCHKLIST")
objAdJoin.selectSingleNode("DOCCHKLIST").appendChild objDom1.firstChild
Debug.Print objAdJoin.xml
End Sub
You will need to check the parseError property to see if there have been any issues with the load. You will also end up with two nodes called DOCCHKLIST.

Classic asp page is throwing "internal server 500 error"

Connection file
<%
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "abc","ID","Password"
conn.commandtimeout=120
Set RS = Server.CreateObject("ADODB.RecordSet")
rs.activeConnection = Conn
%>
Classic ASP file
<%response.buffer = true%>
<%Response.Expires = 0%>
<!-- #include file="functions.asp" -->
<% Response.Write session("RequestID")%>
<%if session("ValidLogon") <> "true" then
if request("FromEmail") = "True" then
SetSessVar()
else%>
<%response.redirect "Default.asp"
end if
end if%>
<html>
<body>
<%rs.Source = "SELECT * from tblRequests WHERE RequestID = " & request("requestID")
rs.Open
session("RequestID") = rs("requestid")
if rs("RequestType") = "O" then
response.clear
If request("Tag") = "Change" then
response.redirect "abc.asp#change"
else
response.redirect "abc.asp?From=" & request("From")
end if
else
response.clear
If request("Tag") = "Change" then
response.redirect "editinternal.asp#change"
else
response.redirect "editinternal.asp?From=" & request("From")
end if
end if
rs.close%>
</body>
</html>
I have checked the classic asp page and it looks like there is an error in syntax inside "Body" tag. I don't know anything about it.
It is giving internal server error 500.
In Connection File you are missing Set on rs.activeConnection = Conn as you are setting an object reference to the ADODB.Connection object instance not passing a connection string.
'Object instances require Set
Set rs.activeConnection = Conn
Please make sure that you configure your site to send the detailed error messages to the client
This describes how:
Show detailed errors
I would guess that your connection "abc"/"ID"/"Password" has to be a real connection. It seems that you just wrote something to see what happens. It could also be the "functions.asp" file that you are including. Does that file exist, what does it contain?
Please post back your detailed error messages, then we can help you better.
Before referencing to the recordset you should check if the recordset contains any records like:
If not rs.eof then
Session("reqestid") = rs("reqestid")
....
End If
Just want to add one trix here, try add these 2 lines right after the body tag
Response.Write "<br>For the sake of debug"
Response.Flush
If you have buffering on, this sometimes writes out the error instead of throwing out error 500. Helps me often.

including classes with a wsc file

Ok, what am i doing wrong here?
i'm trying to include a vbscript with a class inside this way:
SCRIPT.VBS:
set inc = createobject("script.runner")
inc.Include "class"
set x = new test
x.msg' here i get the error 'undefined class'!
REGISTERED .wsc file:
<?xml version="1.0"?>
<component>
<registration
description="wsc"
progid="script.runner"
version="1.00"
classid="{f65e154c-43b3-4f8f-aa3d-535af68f51d1}"
>
</registration>
<public>
<method name="Include">
<PARAMETER name="Script"/>
</method>
</public>
<script language="VBScript">
<![CDATA[
Sub Include(Script)
ExecuteGlobal(CreateObject("scripting.filesystemobject").OpenTextFile(Script & ".vbs", 1).Readall & VBNewLine)
End Sub
]]>
</script>
</component>
CLASS.VBS:
class test
public sub msg
msgbox "hi"
end sub
end class
I was thinking maybe i need to define it in the wsc file if i'm going to use classes or something?
i don't know..
Thanks for any help!
VBscript's Execute(Global) and .COM are very different ways of re-using code. You shouldn't mix them.
A .wsc lets you create one object and use its methods and properties. Such a method (factory) may create and return another object. So if you add
<method name="mkTest">
</method>
...
Function mkTest()
Set mkTest = New test
End Function
to your .wsc and
set x = inc.mkTest
x.msg
to your .vbs, the whole rigmarole will 'work'.
You should think about your real world task, read a good book about .COM, and come up with a simple strategy that does not mix heterogeneous technologies (maybe the Sub Include()/ExecuteGlobal approach sketched here).
did this:
script
set inc = createobject("script.runner")
inc.Include "C:\Users\GEEK\Desktop\small"
set x = inc.AddClass("test")
x.msg' here i get the error 'undefined class'!
inside wsc method
Function AddClass(ClassName)
execute("Set AddClass = New " & ClassName)
end Function
and Ekkehard.Horner,
You're right.
I'm just to curious about how to solve a problem even when there are easier ways to do
something ^^
Thanks for all the help!
regards

Access Connection String From File Generated by Server.Execute

I have a file header.asp that has an server side include head.asp. Inside head.asp my connection to my database is created and is accessible from the header.asp file and pages that use the header.asp file as an server side include (in this case my core.asp file). Inside core.asp I have the following:
if request.querystring("page") = "" then
response.write("<p>No data to load</p>")
else
page = request.querystring("page")
set fso = createobject("scripting.filesystemobject")
FileName = "../Pages/" & page & ".asp"
if fso.FileExists (server.mappath(FileName)) then
Server.Execute(FileName)
else
response.write("<p>Could not validate page. Try again.</p>")
end if
end if
This executes just fine and the proper page renders inside the core.asp file. My issue, is that the connection string (from head.asp) is not available to the file being called from Server.Execute. Thus, I cannot run database queries, etc. on this page unless I were to instantiate the object anew. Is there any way to use the object created?
If I have not explained this properly, I will expound as I am able given my intermediate experience level.
As a follow up to answer #1, if I've followed the logic correctly, I'm attempting to create the connection object at the application level (global.asa):
Sub Application_OnStart()
dim oConn, connectstr
set oConn = Server.CreateObject("ADODB.Connection")
connectstr = "Driver={MySQL ODBC 3.51 Driver};SERVER=theServer; DATABASE=theDatabase; UID=theUserID; PWD=thePassword"
oConn.ConnectionTimeout = 5
oConn.Open connectstr
Application("con") = oConn
end Sub
</script>
Attempting to access the object like so from my page that includes the global.asa as an IIS:
qryAdmin = "select * from table"
set rsAdmin = Application("con").execute(qryAdmin)
The results are the same. I receive the "Object required" error. Any glaring errors that could be causing this?
Assign this object to a session variable and you can access it from any page you like...
Session("MyConnectionObj")= CONN
CONN is your instantiated connection object on the page where you instantiate your connection originally. And in your executed file just call
set NewCONN=Session("MyConnectionObj")
RS.Open strSql ,NewCONN,1,1
where strSql is your SQL, RS is your recordset etc... Obviously if you calling the stored procedure, it will look slightly different but you get the point.
Edited to show that object have to be declared and set before one using it. As I see at least one "expert" did not know that.
Edited base on comments from Window Frog:
did you try it like that:
<%
if request.querystring("page") = "" then
response.write("<p>No data to load</p>")
else
page = request.querystring("page")
set fso = createobject("scripting.filesystemobject")
FileName = "../Pages/" & page & ".asp"
if fso.FileExists (server.mappath(FileName)) then%>
<!--#include file="<%=FileName %>" -->
<% else
response.write("<p>Could not validate page. Try again.</p>")
end if
end if
%>

VBScript and loadXML: Invalid at the top level of the document. How to fix it?

This is my fort post on stackoverflow. I have searched many similiar Q&A's on this site but my conditions seem a bit different. here is my vbscript code:
------------ code snippet ---------------
xmlurl = "songs.xml"
set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = False
xmlDoc.loadXML(xmlurl)
if xmlDoc.parseError.errorcode<>0 then
'error handling code
msgbox("error! " & xmlDoc.parseError.reason)
end if
------------ end code snippet ---------------
XML:
<?xml version="1.0" encoding="UTF-8"?>
<nowplaying-info-list>
<nowplaying-info mountName="CKOIFMAAC" timestamp="1339771946" type="track">
<property name="track_artist_name"><![CDATA[CKOI]]></property>
<property name="cue_title"><![CDATA[HITMIX]]></property>
</nowplaying-info>
<nowplaying-info mountName="CKOIFMAAC" timestamp="1339771364" type="track">
<property name="track_artist_name"><![CDATA[AMYLIE]]></property>
<property name="cue_title"><![CDATA[LES FILLES]]></property>
</nowplaying-info>
<nowplaying-info mountName="CKOIFMAAC" timestamp="1339771149" type="track">
<property name="track_artist_name"><![CDATA[MIA MARTINA]]></property>
<property name="cue_title"><![CDATA[TOI ET MOI]]></property>
</nowplaying-info>
</nowplaying-info-list>
I also tried removing the first line in case maybe UTF-8 was not compatible with windows (saw some posts about this), but I still got the same error. I also tried unix2dos and vice versa in case there were carriage return issues (hidden characters embedded in the xml). I just can't seem to figure out what's wrong. It's such a simole XML file. I could parse it in a few minutes using perl regex but I need to run this script on windows so using vbscript. I use the same technique to parse XML from other sources without any issues. I cannot modify the XML unfortunately, it is from an external source.
I have this exact same error on both my Windows Vista home edition and Windows Server 2008. I am running the vbscript from the command line for testing so far (ie not in ASP).
Thanks in advance,
Sam
xmlDoc.loadXML() can load an XML string. It cannot retrieve a URL.
Use an XMLHTTPRequest object if you need to make an HTTP request.
Function LoadXml(xmlurl)
Dim xmlhttp
Set xmlhttp = CreateObject("MSXML2.XMLHTTP")
xmlhttp.Open "GET", xmlurl, false
' switch to manual error handling
On Error Resume Next
xmlhttp.Send
If err.number <> 0 Then
WScript.Echo xmlhttp.parseError.Reason
Err.Clear
End If
' switch back to automatic error handling
On Error Goto 0
Set LoadXml = xmlhttp.ResponseXml
End Function
Use like
Set doc = LoadXml("http://your.url/here")
Three addition remarks:
(1) As .parseError.reason tends to be cryptic, it pays to include its .srcTxt
property (and the parameter to .loadXml):
Dim xmlurl : xmlurl = "song.xml"
Dim xmlDoc : Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = False
xmlDoc.loadXML xmlurl
If 0 <> xmlDoc.parseError.errorcode Then
WScript.Echo xmlDoc.parseError.reason, "Src:", xmlDoc.parseError.srcText
Else
WScript.Echo "surprise, surprise"
End if
output:
Invalid at the top level of the document.
Src: song.xml
Of course, writing a Function/Sub that takes all properties of .parseError
into account and using that always, would be even better.
(2) To load a file or URL, use .load:
Dim xmlDoc : Set xmlDoc = CreateObject("Microsoft.XMLDOM")
Dim xmlurl
For Each xmlurl In Array("song.xml", "http://gent/~eh/song.xml", "zilch")
xmlDoc.async = False
if xmlDoc.load(xmlurl) Then
With xmlDoc.documentElement.firstChild
WScript.Echo xmlurl _
, .tagName _
, .firstChild.tagName _
, .firstChild.text
End With
Else
WScript.Echo xmlurl, xmlDoc.parseError.reason, "Src:", xmlDoc.parseError.srcText
End if
Next
output:
song.xml nowplaying-info property CKOI-ÄÖÜ
http://gent/~eh/song.xml nowplaying-info property CKOI-ÄÖÜ
zilch The system cannot locate the object specified.
Src:
(3) Using the DOM avoids all encoding problems (that's why I put some
german umlauts into 'your' file - which even made it to the DOS-Box output)
and makes RegExps (even Perl's) a second best choice.

Resources