I have done almost the same. I got the load-method to work by changing the parameters to load(a,a,a,a,b). This makes it possible to pass a VARIANT in chunks of 4 LONG's. This is not ideal, but it works. I don't know if it's possible to change this behaviour.
Please look at my code. I've been able to load XML and XSL and perform a transform. The output looks very nice. I also added some code to walk down a node.
The code is below. You can download including the XML and XSL from:
Code: Select all
;---------------------------------------------------------------------------------------------
; This program uses the MSXML interface to work with XML and XSL
;
; aXend, 2004
;---------------------------------------------------------------------------------------------
; Variant stuff
Enumeration
#VT_EMPTY = 0
#VT_NULL = 1
#VT_I2 = 2
#VT_I4 = 3
#VT_R4 = 4
#VT_R8 = 5
#VT_CY = 6
#VT_DATE = 7
#VT_BSTR = 8
#VT_DISPATCH = 9
#VT_ERROR = 10
#VT_BOOL = 11
#VT_VARIANT = 12
#VT_UNKNOWN = 13
#VT_DECIMAL = 14
#VT_I1 = 16
#VT_UI1 = 17
#VT_UI2 = 18
#VT_UI4 = 19
#VT_I8 = 20
#VT_UI8 = 21
#VT_INT = 22
#VT_UINT = 23
#VT_VOID = 24
#VT_HRESULT = 25
#VT_PTR = 26
#VT_SAFEARRAY = 27
#VT_CARRAY = 28
#VT_USERDEFINED = 29
#VT_LPSTR = 30
#VT_LPWSTR = 31
#VT_RECORD = 36
#VT_FILETIME = 64
#VT_BLOB = 65
#VT_STREAM = 66
#VT_STORAGE = 67
#VT_STREAMED_OBJECT = 68
#VT_STORED_OBJECT = 69
#VT_BLOB_OBJECT = 70
#VT_CF = 71
#VT_CLSID = 72
#VT_BSTR_BLOB = $0fff
#VT_VECTOR = $1000
#VT_ARRAY = $2000
#VT_BYREF = $4000
#VT_RESERVED = $8000
#VT_ILLEGAL = $ffff
#VT_ILLEGALMASKED = $0fff
#VT_TYPEMASK = $0fff
EndEnumeration
Structure VARIANT
vt.w
wReserved1.w
wReserved2.w
wReserved3.w
StructureUnion
value.l
bstrVal.l
scode.l
EndStructureUnion
EndStructure
;- Constants
#DISP_E_PARAMNOTFOUND = $80020004
#CRLF.s = Chr(13)+Chr(10)
#BR.s = "<br>"
Enumeration
#Window
#Statusbar
#ButtonBack
#ButtonNext
#ButtonStop
#ButtonGo
#Url
#Frame
#Webpage
EndEnumeration
;- Interface definitions
Interface myIXMLDOMNode Extends IDispatch
get_nodeName(a.l) ;
get_nodeValue(a.l) ;
put_nodeValue(a.l) ;
get_nodeType(a.l) ;
get_parentNode(a.l) ;
get_childNodes(a.l) ;
get_firstChild(a.l) ;
get_lastChild(a.l) ;
get_previousSibling(a.l) ;
get_nextSibling(a.l) ;
get_attributes(a.l) ;
insertBefore(a.l,b.l,c.l) ;
replaceChild(a.l,b.l,c.l) ;
removeChild(a.l,b.l) ;
appendChild(a.l,b.l) ;
hasChildNodes(a.l) ;
get_ownerDocument(a.l) ;
cloneNode(a.l,b.l) ;
get_nodeTypeString(a.l) ;
get_text(a.l) ;
put_text(a.l) ;
get_specified(a.l) ;
get_definition(a.l) ;
get_nodeTypedValue(a.l) ;
put_nodeTypedValue(a.l) ;
get_dataType(a.l) ;
put_dataType(a.l) ;
get_xml(a.l) ;
transformNode(a.l,b.l) ;
selectNodes(a.l,b.l) ;
selectSingleNode(a.l,b.l) ;
get_parsed(a.l) ;
get_namespaceURI(a.l) ;
get_prefix(a.l) ;
get_baseName(a.l) ;
transformNodeToObject(a.l,b.l) ;
EndInterface
Interface myIXMLDOMNodeList Extends IDispatch
get_item(a.l,b.l) ;
get_length(a.l) ;
nextNode(a.l) ;
reset() ;
get__newEnum(a.l) ;
EndInterface
Interface myIXMLDOMDocument Extends myIXMLDOMNode
get_doctype(a.l) ;
get_implementation(a.l) ;
get_documentElement(a.l) ;
put_documentElement(a.l) ;
createElement(a.l,b.l) ;
createDocumentFragment(a.l) ;
createTextNode(a.l,b.l) ;
createComment(a.l,b.l) ;
createCDATASection(a.l,b.l) ;
createProcessingInstruction(a.l,b.l,c.l) ;
createAttribute(a.l,b.l) ;
createEntityReference(a.l,b.l) ;
getElementsByTagName(a.l,b.l) ;
createNode(a.l,b.l,c.l,d.l) ;
nodeFromID(a.l,b.l) ;
load(a.l,a.l,a.l,a.l,b.l) ; I changed this method to pass a VARIANT to it
get_readyState(a.l) ;
get_parseError(a.l) ;
get_url(a.l) ;
get_async(a.l) ;
put_async(a.l) ;
abort() ;
loadXML(a.l,b.l) ;
save(a.l) ;
get_validateOnParse(a.l) ;
put_validateOnParse(a.l) ;
get_resolveExternals(a.l) ;
put_resolveExternals(a.l) ;
get_preserveWhiteSpace(a.l) ;
put_preserveWhiteSpace(a.l) ;
put_onreadystatechange(a.l) ;
put_ondataavailable(a.l) ;
put_ontransformnode(a.l) ;
EndInterface
Interface myIXMLDOMParseError Extends IDispatch
get_errorCode(a.l) ;
get_url(a.l) ;
get_reason(a.l) ;
get_srcText(a.l) ;
get_line(a.l) ;
get_linepos(a.l) ;
get_filepos(a.l) ;
EndInterface
;- Variables
Global oXML.myIXMLDOMDocument
Global oXSL.myIXMLDOMDocument
vTRUE.VARIANT\vt = #VT_BOOL
vTRUE\value = $FFFF
vFALSE.VARIANT\vt = #VT_BOOL
vFALSE\value = $0
;I use this to pass a VARIANT to a method
Structure pToVariant
a.l[4]
EndStructure
;---------------------------------------------------------------------------------------------
;- Unicode procedures
;---------------------------------------------------------------------------------------------
Procedure.s Uni2Ansi(unicodestr.l)
lenA = WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, 0, 0, 0, 0);
ansistr.s = Space(lenA)
If (lenA > 0)
WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, @ansistr, lenA, 0, 0);
EndIf
ProcedureReturn ansistr
EndProcedure
Procedure.l Ansi2Uni(ansistr.s)
lenA.l = Len(ansistr)
lenW = MultiByteToWideChar_(#CP_ACP, 0, ansistr, lenA, 0, 0)
If (lenW > 0) ; Check whether conversion was successful
unicodestr = SysAllocStringLen_(0, lenW)
MultiByteToWideChar_(#CP_ACP, 0, ansistr, lenA, unicodestr, lenW)
result = unicodestr
SysFreeString_(unicodestr)
ProcedureReturn result
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure ResizeWebWindow()
ResizeGadget(#Webpage, -1, -1, WindowWidth(), WindowHeight()-52)
ResizeGadget(#Url, -1, -1, WindowWidth()-185, -1)
ResizeGadget(#ButtonGo, WindowWidth()-25, -1, -1, -1)
ResizeGadget(#Frame, -1, -1, WindowWidth(), -1)
EndProcedure
Procedure SizeCallback(WindowID, Message, wParam, lParam)
ReturnValue = #PB_ProcessPureBasicEvents
If Message = #WM_SIZE
; UpdateStatusBar(0)
ResizeWebWindow()
ReturnValue = 1
EndIf
ProcedureReturn ReturnValue
EndProcedure
;---------------------------------------------------------------------------------------------
;Browse file
;---------------------------------------------------------------------------------------------
Procedure Browse(url.s)
If OpenWindow(#Window, 100, 200, 800, 500, #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget, "PureBasic XMLBrowser v1.0")
CreateStatusBar(#Statusbar, WindowID())
StatusBarText(#Statusbar, 0, "Welcome to the world of Interfacing ! :)", 0)
CreateGadgetList(WindowID())
ButtonGadget(#ButtonBack, 0, 0, 50, 25, "Back")
ButtonGadget(#ButtonNext, 50, 0, 50, 25, "Next")
ButtonGadget(#ButtonStop, 100, 0, 50, 25, "Stop")
StringGadget(#Url, 155, 5, 0, 20, url)
ButtonGadget(#ButtonGo, 0, 0, 25, 25, "Go")
Frame3DGadget(#Frame, 0, 30, 0, 2, "", 2) ; Nice little separator
If WebGadget(#Webpage, 0, 31, 0, 0, url) = 0 : MessageRequester("Error", "ATL.dll not found", 0)
End
EndIf
AddKeyboardShortcut(#Window, #PB_Shortcut_Return, 0)
ResizeWebWindow()
SetWindowCallback(@SizeCallback())
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadgetID()
Case #ButtonBack
SetGadgetState(#Webpage, #PB_Web_Back)
Case #ButtonNext
SetGadgetState(#Webpage, #PB_Web_Forward)
Case #ButtonStop
SetGadgetState(#Webpage, #PB_Web_Stop)
Case #Url
SetGadgetText(#Webpage, GetGadgetText(#Url))
EndSelect
Case #PB_Event_Menu ; We only have one shortcut
SetGadgetText(#Webpage, GetGadgetText(#Url))
EndSelect
Until Event = #PB_Event_CloseWindow
CloseWindow(#Window)
SetWindowCallback(#Null)
EndIf
EndProcedure
;---------------------------------------------------------------------------------------------
;Write the html to a file to display in browser
;---------------------------------------------------------------------------------------------
Procedure Write(html.s)
filename.s = "temp.htm"
path.s = Space(1000)
GetCurrentDirectory_(1000,@path)
hFile = CreateFile(#PB_Any, filename)
If hFile
WriteString(html)
CloseFile(hFile)
Browse("file://" + path + "\" + filename)
If DeleteFile(filename) = 0
MessageRequester("Error","Could not delete tempfile",0)
EndIf
Else
MessageRequester("Error","Could not create tempfile",0)
EndIf
EndProcedure
;---------------------------------------------------------------------------------------------
;Show XML errors
;---------------------------------------------------------------------------------------------
Procedure XMLError()
oXML\get_parseError(@oError.myIXMLDOMParseError)
oError\get_errorCode(@errorcode.l)
oError\get_reason(@reason)
reason$ = Uni2Ansi(reason)
oError\get_srcText(@srctext) ;
Debug Uni2Ansi(srctext)
oError\get_line(@line) ;
oError\get_linepos(@linepos) ;
srctxt$ = Uni2Ansi(srctext)
srctxt$ = ReplaceString(srctxt$,"<","<")
srctxt$ = ReplaceString(srctxt$,">",">")
msg.s = "<font face='Courier New, Courier, mono' size='2'>"
msg = msg + reason$ + #BR
msg = msg + "at line " + Str(line) + " at position " + Str(linepos) + #BR
msg = msg + srctxt$ + #BR
msg = msg + RSet("^",linepos,"-")
msg = msg + "</font>"
Write(msg)
oError\Release()
Goto Finish
EndProcedure
;---------------------------------------------------------------------------------------------
;Transform the XML file with the XSL file make up by XSLT
;---------------------------------------------------------------------------------------------
Procedure Transform()
If oXML\transformNode(oXSL,@transform.l) = #S_OK
Write(Uni2Ansi(transform))
Else
SetErrorNumber(err)
EndIf
EndProcedure
;---------------------------------------------------------------------------------------------
;Scan all the elements of a given tagname
;---------------------------------------------------------------------------------------------
Procedure ShowElements(tagname.s)
nodetxt.s = Space(1000)
If oXML\getElementsByTagName(Ansi2Uni(tagname),@oNodelist.myIXMLDOMNodeList) = #S_OK
oNodelist\get_length(@length)
For i=0 To length-1
oNodelist\get_item(i,@oNode.myIXMLDOMNode)
oNode\get_nodeName(@name)
oNode\get_text(@value) ;
nodetxt = nodetxt + Uni2Ansi(name)+":"+Uni2Ansi(value) + #BR
oNodelist\NextNode(@oNode.myIXMLDOMNode)
Next
Write(nodetxt)
Else
XMLError()
EndIf
If oNode
oNode\Release()
EndIf
If oNodelist
oNodelist\Release()
EndIf
EndProcedure
;---------------------------------------------------------------------------------------------
;- Start of program
;---------------------------------------------------------------------------------------------
OnErrorGoto(?Error)
CoInitialize_(0)
If CoCreateInstance_(?CLSID_XMLDOM,0,1,?IID_IXMLDOMDocument,@oXML)<>#S_OK
MessageRequester("Warning:","Couldn't init oXML",0)
End
EndIf
Debug oXML
If CoCreateInstance_(?CLSID_XMLDOM,0,1,?IID_IXMLDOMDocument,@oXSL)<>#S_OK
MessageRequester("Warning:","Couldn't init oXML",0)
End
EndIf
Debug oXSL
;---------------------------------------------------------------------------------------------
;Turn off asynchronized loading, to make sure that the parser will not continue execution before the document is fully loaded
;---------------------------------------------------------------------------------------------
oXML\put_async(#False)
;---------------------------------------------------------------------------------------------
;The XML file must be passed as VARIANT
;---------------------------------------------------------------------------------------------
loadXML.VARIANT\vt = #VT_BSTR
loadXML\bstrVal = Ansi2Uni("test_ie.xml")
;---------------------------------------------------------------------------------------------
;At the moment the VARIANT needs to be split in 4 LONGS to pass to MSXML
;---------------------------------------------------------------------------------------------
*V1.pToVariant = loadXML
;---------------------------------------------------------------------------------------------
;Load the document
;---------------------------------------------------------------------------------------------
If oXML\load(*V1\a[0],*V1\a[1],*V1\a[2],*V1\a[3],@success.l) <> #S_OK
XMLError()
EndIf
;---------------------------------------------------------------------------------------------
;Turn off asynchronized loading, to make sure that the parser will not continue execution before the document is fully loaded
;---------------------------------------------------------------------------------------------
oXSL\put_async(#False)
;---------------------------------------------------------------------------------------------
;The XML file must be passed as VARIANT
;---------------------------------------------------------------------------------------------
loadXSL.VARIANT\vt = #VT_BSTR
loadXSL\bstrVal = Ansi2Uni("test_ie.xsl")
;---------------------------------------------------------------------------------------------
;At the moment the VARIANT needs to be split in 4 LONGS to pass to MSXML
;---------------------------------------------------------------------------------------------
*V2.pToVariant = loadXSL
;---------------------------------------------------------------------------------------------
;Load the document
;---------------------------------------------------------------------------------------------
If oXSL\load(*V2\a[0],*V2\a[1],*V2\a[2],*V2\a[3],@success.l) <> #S_OK
XMLError()
EndIf
;---------------------------------------------------------------------------------------------
;This procedure will show the XML file in the format as defined by the XSL file
;---------------------------------------------------------------------------------------------
Transform()
;---------------------------------------------------------------------------------------------
;This procedure will show the content of a given elementtag
;---------------------------------------------------------------------------------------------
ShowElements("Name")
;---------------------------------------------------------------------------------------------
;- End program
;---------------------------------------------------------------------------------------------
Finish:
If oXSL
oXSL\Release()
EndIf
If oXML
oXML\Release()
EndIf
CoUninitialize_()
End
;---------------------------------------------------------------------------------------------
;- Error handler
;---------------------------------------------------------------------------------------------
Error:
error.s = Space(500)
error = GetErrorDescription()
MessageRequester("Error", Str(GetErrorLineNR()) + ":" + error + " (" + Hex(GetErrorNumber()) + " )" + #CRLF, 0)
Goto Finish
;---------------------------------------------------------------------------------------------
;- Datasection
;---------------------------------------------------------------------------------------------
DataSection
CLSID_XMLDOM: ;{2933BF90-7B36-11D2-B20E-00C04F983E60}
Data.l $2933BF90
Data.w $7B36,$11D2
Data.b $B2,$0E,$00,$C0,$4F,$98,$3E,$60
EndDataSection
DataSection
IID_IXMLDOMDocument: ;{2933BF81-7B36-11D2-B20E-00C04F983E60}
Data.l $2933BF81
Data.w $7B36,$11D2
Data.b $B2,$0E,$00,$C0,$4F,$98,$3E,$60
EndDataSection