Re: Reading XML (data) files in eMbedded Visual Basic.
From: Tony (icbm_NO_SPAM_at_PLEASE_hetnet.nl)
Date: 11/15/04
- Previous message: Kabouterbond: "Reading XML (data) files in eMbedded Visual Basic."
- In reply to: Kabouterbond: "Reading XML (data) files in eMbedded Visual Basic."
- Messages sorted by: [ date ] [ thread ]
Date: Mon, 15 Nov 2004 19:18:23 GMT
There is the DOM object on the PPC that can be used.
In my projects I know the fields I want, so I can approach them directly.
But here is some code samples:
(Get the API file read/write for free ;-)
(Oh, as you know CreateObject leaks, so only call it once, re-use the object
when needed)
' For the DOM
Private xmlDOM As DOMDocument ' The XML parser...
Private mDOMLoaded As Boolean ' Indication DOM object is loaded
Private mDOMFile As String ' Current filename in DOM memory
Private mDOMTag As Integer ' Project related variable, can be
removed (everywhere)
Private mDOMMemoryFile As String
Private mDOMMemoryTag As Integer
' Needed to read/write files
Public Const CREATE_ALWAYS = 2
Public Const OPEN_EXISTING = 3
Public Const OPEN_ALWAYS = 4
Public Const STANDARD_RIGHTS_WRITE = &H20000
Public Const STANDARD_RIGHTS_READ = &H20000
Public Const GENERIC_READ = &H80000000
Public Const GENERIC_WRITE = &H40000000
Public Const INVALID_HANDLE_VALUE = -1
Public Declare Function CreateFile Lib "Coredll" Alias "CreateFileW" (ByVal
lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As
Long, lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long,
ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Public Declare Function GetFileSize Lib "Coredll" (ByVal hFile As Long,
lpFileSizeHigh) As Long
Public Declare Function ReadFile Lib "Coredll" (ByVal hFile As Long, ByVal
lpBuffer As String, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead
As Long, ByVal lpOverlapped As Long) As Long
Public Declare Function WriteFile Lib "Coredll" (ByVal hFile As Long, ByVal
lpBuffer As String, ByVal nNumberOfBytesToWrite As Long,
lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long
Public Declare Function CloseHandle Lib "Coredll" (ByVal hObject As Long) As
Long
Public Declare Function FlushFileBuffers Lib "Coredll" (ByVal hFile As Long)
As Long
Public Declare Function WideCharToMultiByte Lib "Coredll" (ByVal CodePage As
Long, ByVal dwFlags As Long, ByVal lpWideCharStr As String, ByVal
cchWideChar As Long, ByVal lpMultiByteStr As String, ByVal cchMultiByte As
Long, ByVal lpDefaultChar As String, ByVal lpUsedDefaultChar As Long) As
Long
Public Declare Function MultiByteToWideChar Lib "Coredll" (ByVal CodePage As
Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As String, ByVal
cchMultiByte As Long, ByVal lpWideCharStr As String, ByVal cchWideChar As
Long) As Long
'
Public Const CP_ACP = 0 ' default to ANSI code page
' --- The methods ---
Public Sub Initialise_DOM()
On Error Resume Next
' Init DOM
Err.Clear
Set xmlDOM = CreateObject("Microsoft.XMLDOM") ' Create a DOMDocument
mDOMLoaded = CBool(Err.Number = 0)
If mDOMLoaded Then xmlDOM.async = False ' Return control after
the whole string has been loaded
End Sub
Public Sub Terminate_DOM()
' Close DOM
Set xmlDOM = Nothing
End Sub
' Load into DOM
Public Function XML_Load(ByVal xmlFile As String, ByVal Tag As Integer) As
Boolean
Dim sXMLContents As String
On Error Resume Next
XML_Load = False
If Not mDOMLoaded Then ' No object...
Exit Function
ElseIf mDOMFile = UCase(xmlFile) Then ' Already loaded
XML_Load = True
Exit Function
End If
' This would be the easiest way to load the file into the parser, but...
' Returns an "Access Denied" error in the emulator and on a device
'xmlDOM.Load xmlFile
'
' Instead, open the XML file with the file control and store the
contents in a string
'
sXMLContents = ReadTextFile(xmlFile)
If Len(Trim(sXMLContents)) = 0 Then Exit Function ' No contents...
mDOMFile = ""
mDOMTag = -1
' Load the XML string into the parser
xmlDOM.loadXML sXMLContents
' Check to see if the XML document is valid
If xmlDOM.parseError.errorCode <> 0 Then Exit Function
mDOMFile = UCase(xmlFile)
mDOMTag = Tag
XML_Load = True
End Function
Public Sub XML_Memorise(ByVal SaveState As Boolean)
On Error Resume Next
If Not mDOMLoaded Then Exit Sub
If SaveState Then
mDOMMemoryFile = mDOMFile
mDOMMemoryTag = mDOMTag
ElseIf Len(mDOMMemoryFile) = 0 Then
XML_Clear
Else
XML_Load mDOMMemoryFile, mDOMMemoryTag
End If
End Sub
Public Sub XML_Clear()
On Error Resume Next
If Not mDOMLoaded Then Exit Sub
If Len(mDOMFile) = 0 Then Exit Sub
xmlDOM.loadXML ""
mDOMFile = ""
mDOMTag = -1
End Sub
Public Function XML_Instance() As Boolean
XML_Instance = mDOMLoaded
End Function
Public Function XML_Tag() As Integer
XML_Tag = mDOMTag
End Function
Public Function XML_File() As String
XML_File = mDOMFile
End Function
' Use DOM to get value. Make sure to use LoadXML to set required XML file.
Public Function XML_Value(ByVal xmlKey As String, ByVal xmlDefault As
String) As String
On Error Resume Next
Dim nodeX As Object ' IXMLDOMNode
If mDOMLoaded Then
'Set nodeX = xmlDOM.selectSingleNode(".//" & node_name)
Set nodeX = xmlDOM.selectSingleNode(xmlKey)
If nodeX Is Nothing Then
XML_Value = xmlDefault
Else
XML_Value = nodeX.Text
End If
Else
XML_Value = xmlDefault
End If
End Function
' When key is missing, a new key will be created.
Public Sub XML_SetValue(ByVal xmlKey As String, ByVal xmlValue As String)
On Error Resume Next
If Not mDOMLoaded Then Exit Sub
Dim nodeX As Object ' IXMLDOMNode
Set nodeX = xmlDOM.selectSingleNode(xmlKey)
If nodeX Is Nothing Then
XML_CreateKey xmlKey
Set nodeX = xmlDOM.selectSingleNode(xmlKey)
End If
nodeX.Text = xmlValue
End Sub
Public Sub XML_CreateKey(ByVal xmlKey As String)
Dim nMark As Long
Dim nOffset As Long
Dim sChildKey As String
Dim sParentKey As String
Dim parentX As Object
Dim nodeX As Object ' IXMLDOMNode
On Error Resume Next
If Not mDOMLoaded Then Exit Sub
If Mid(xmlKey, 1, 1) <> "/" Then xmlKey = "/" & xmlKey
If Right(xmlKey, 1) = "/" Then xmlKey = Mid(xmlKey, 1, Len(xmlKey) - 1)
nOffset = 2
Do While True
If nOffset > Len(xmlKey) Then Exit Do
sParentKey = Mid(xmlKey, 1, nOffset - 2)
nMark = InStr(nOffset, xmlKey, "/", vbBinaryCompare)
If nMark = 0 Then nMark = Len(xmlKey) + 1
sChildKey = Mid(xmlKey, nOffset, nMark - nOffset)
nOffset = nMark + 1
' Does it exists?
Set nodeX = xmlDOM.selectSingleNode(sParentKey & "/" & sChildKey)
If nodeX Is Nothing Then
' Nope: Create.
If Len(sParentKey) = 0 Then
Set nodeX = xmlDOM.ownerDocument.createElement(sChildKey)
xmlDOM.appendChild nodeX
Else
Set parentX = xmlDOM.selectSingleNode(sParentKey)
Set nodeX = parentX.ownerDocument.createElement(sChildKey)
parentX.appendChild nodeX
End If
End If
Loop
End Sub
Public Function XML_Save(ByVal xmlFile As String) As Boolean
On Error Resume Next
XML_Save = CreateTextFile(xmlFile, xmlDOM.xml)
End Function
' --- File read/write methods ---
Public Function ReadTextFile(ByVal FileName As String) As String
Dim hFile As Long
Dim nSize As Long
Dim Contents As String
Dim dwRead As Long
Dim sUnicode As String
ReadTextFile = ""
' get file size
hFile = CreateFile(FileName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0)
If hFile = INVALID_HANDLE_VALUE Then Exit Function
nSize = GetFileSize(hFile, 0)
If nSize > 0 Then
' allocate space for contents (ANSI = 1 byte/char, but VB stores
strings as 2 bytes/char)
If (nSize Mod 2) = 0 Then
Contents = String(nSize \ 2, 0)
Else
Contents = String((nSize \ 2) + 1, 0)
End If
' get contents
ReadFile hFile, Contents, nSize, dwRead, 0
' convert ANSI (1 byte/char) to Unicode (2 bytes/char)
sUnicode = String(dwRead, 0) ' Unicode is 2 bytes per character
Call MultiByteToWideChar(CP_ACP, 0, Contents, dwRead, sUnicode,
dwRead)
ReadTextFile = sUnicode
End If
CloseHandle hFile
End Function
Public Function CreateTextFile(ByVal FileName As String, ByRef Contents As
String) As Boolean
Dim sANSI As String
Dim hFile As Long
Dim lWritten As Long
On Error Resume Next
CreateTextFile = False
' Create file
hFile = CreateFile(FileName, GENERIC_READ + GENERIC_WRITE, 0, 0,
CREATE_ALWAYS, 0, 0)
If hFile = INVALID_HANDLE_VALUE Then Exit Function
' Now convert Unicode contents to ANSI
sANSI = UnicodeToANSI(Contents)
' Write the ANSI bytes
WriteFile hFile, sANSI, LenB(sANSI), lWritten, 0
FlushFileBuffers hFile
CloseHandle hFile
' Verify the bytes are written
CreateTextFile = CBool(lWritten = LenB(sANSI))
End Function
' Convert Unicode (2 bytes/char) to ANSI (1 byte/char)
'
' (Slow) eVB code:
' For i = 1 To LenB(ContentsUnicode) Step 2
' ContentsANSI = ContentsANSI & MidB(ContentsUnicode, i, 1)
' Next
'
Public Function UnicodeToANSI(ByVal ContentsUnicode As String) As String
Dim ContentsANSI As String
Dim nSize As Long
nSize = Len(ContentsUnicode)
ContentsANSI = String((nSize \ 2) + 1, 0) ' VB stores strings as 2
bytes/char, so you must divide count with 2
Call WideCharToMultiByte(CP_ACP, 0, ContentsUnicode, nSize,
ContentsANSI, nSize, 0, 0)
UnicodeToANSI = MidB(ContentsANSI, 1, nSize)
End Function
"Kabouterbond" <kabouterbond@planet.nl> schreef in bericht
news:cnapdp$54p$1@reader10.wxs.nl...
> Dear All,
>
> I would like te write a programme that converts XML (data) files in to CSV
> files on the PPC.
> I already wrote a programme that is able to read and write text files.
>
> The problem is I can't find any information about reading XML files in
> eMbedded Visual Basic.
>
> Is there anyone that can help me starting this programme.
>
> Some lines of code with explanation would be very nice.
>
> Thanks in advance,
>
> Alex.
>
> --
- Previous message: Kabouterbond: "Reading XML (data) files in eMbedded Visual Basic."
- In reply to: Kabouterbond: "Reading XML (data) files in eMbedded Visual Basic."
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|