Hello all
I need you to manipulate an XML file using VBA. I guess you have already done this.
What are the references to use?
Do you have samples to open, read, search in XML files?
I want to read XML files containing values to update PcVue variables.
Thanks
Hello Tony,
To answer quickly... I have already done such a manipulation.
Find here an example, if it can help you. It is a part of a module I had writen for a customer.
The reference was - if I remember - Microsoft XML 6.0 (or sth like that) :
(...)
Const CONST_ConfigFile = "C1ConfigurationGestionDoc_Config.xml"
Const CONST_MaxSymbol = 1000
Const XE_ROOT = "DocManagement"
Const XE_APPS = "Applications"
Const XE_APP = "Application"
Const XE_DOC = "Document"
Const XE_SYM = "LinkedSymbol"
Const XE_FIELDS = "Fields"
Const XE_FIELD = "Field"
Const XE_LINKS = "Links"
Const XE_LINK = "Link"
Const XA_ID = "Id"
Const XA_EXE = "Exe"
Const XA_FILE = "File"
Const XA_NAME = "Name"
Const XA_PREFIX = "Prefix"
Const XA_LINE = "Line"
Const XA_DESCRIPTION = "Description"
Const XA_APPLI = "Application"
Dim mConfigLoaded As Boolean
Dim mConfigFile As String
Dim mXlsDocFile As String
Dim mSymbolName As String
Dim mSymbolPrefix As String
(...)
Private Sub LoadConfigFile()
On Error GoTo TRAP_Error
Dim xDoc As New MSXML2.DOMDocument
Dim xEltApp As MSXML2.IXMLDOMElement
Dim xEltDoc As MSXML2.IXMLDOMElement
Dim xElt As MSXML2.IXMLDOMElement
Dim sId As String
Dim sLine As String
Dim sApp As String
Dim sMessage As String
mConfigLoaded = False
mConfigFile = ThisProject.Path & CONST_ConfigFile
If FileExists(mConfigFile) = False Then
sMessage = "Le fichier de configuration " & mConfigFile & " est introuvable." & _
vbCrLf & "Impossible de charger la gestion documentation."
MsgboxInformation sMessage
GoTo TRAP_Exit
End If
If xDoc.Load(mConfigFile) = False Then
sMessage = "Impossible de charger le fichier de configuration " & mConfigFile & "." & _
vbCrLf & "Vérifiez qu'il est bien au format XML."
MsgboxInformation sMessage
GoTo TRAP_Exit
End If
Set xEltApp = xDoc.SelectSingleNode("//" & XE_ROOT & "/" & XE_APPS)
Set xEltDoc = xDoc.SelectSingleNode("//" & XE_ROOT & "/" & XE_DOC)
If (xEltApp Is Nothing) Or (xEltDoc Is Nothing) Then
sMessage = "Le fichier de configuration " & CONST_ConfigFile & " ne respecte pas le format attendu." & _
vbCrLf & "Impossible de charger la gestion documentation."
MsgboxInformation sMessage
GoTo TRAP_Exit
End If
'Document Excel
mXlsDocFile = xEltDoc.getAttribute(XA_FILE)
If FileExists(mXlsDocFile) = True Then
'Vrai
ElseIf FileExists(ThisProject.Path & mXlsDocFile) = True Then
mXlsDocFile = ThisProject.Path & mXlsDocFile
ElseIf FileExists(ThisProject.Path & "" & mXlsDocFile) = True Then
mXlsDocFile = ThisProject.Path & "" & mXlsDocFile
Else
sMessage = "Le fichier Excel de documentation " & mXlsDocFile & " n'existe pas. Le champ accepte les chemins absolus et relatifs par rapport au projet " & ThisProject.Path & "." & _
vbCrLf & "Impossible de charger la gestion documentation."
MsgboxInformation sMessage
GoTo TRAP_Exit
End If
Set xElt = xEltDoc.SelectSingleNode("//" & XE_SYM)
mSymbolName = xElt.getAttribute(XA_NAME)
mSymbolPrefix = xElt.getAttribute(XA_PREFIX)
For Each xElt In xEltDoc.SelectNodes("//" & XE_FIELDS & "/" & XE_FIELD)
sId = xElt.getAttribute(XA_ID)
sLine = xElt.getAttribute(XA_LINE)
Select Case sId
Case "Ref": mLineRefId = CInt(sLine)
Case "Name": mLineName = CInt(sLine)
Case "Localisation": mLineLoc = CInt(sLine)
Case "Material": mLineMat = CInt(sLine)
Case "CTRA": mLineCTRA = CInt(sLine)
Case "Tel": mLineTel = CInt(sLine)
Case "Ip": mLineIp = CInt(sLine)
End Select
Next
For Each xElt In xEltDoc.SelectNodes("//" & XE_LINKS & "/" & XE_LINK)
sId = xElt.getAttribute(XA_ID)
sLine = xElt.getAttribute(XA_LINE)
Set xElt = xEltApp.SelectSingleNode("//" & XE_APP & "[@" & XA_ID & "='" & xElt.getAttribute(XA_APPLI) & "']")
sApp = xElt.getAttribute(XA_EXE)
Select Case sId
Case "Hydro":
mLineHydro = CInt(sLine)
mExeHydro = sApp
Case "Elec":
mLineElec = CInt(sLine)
mExeElec = sApp
Case "Doc":
mLineDoc = CInt(sLine)
mExeDoc = sApp
Case "Free":
mLineFree = CInt(sLine)
mExeFree = sApp
Case "Other":
mLineOther = CInt(sLine)
mExeOther = sApp
End Select
Next
mConfigLoaded = True
TRAP_Exit:
Set xDoc = Nothing
Exit Sub
TRAP_Error:
sMessage = "Le chargement du fichier XML de configuration '" & mConfigFile & _
"' a rencontré une erreur due à la non-conformité du fichier." & vbCrLf & _
"Vérifiez les balises et attributs du fichier XML." & vbCrLf & vbCrLf & _
"Description VBA de l'erreur : " & Err.Description
ErrManagement sMessage, "LoadConfigFile"
End Sub
That's good but, only to extract data, it's better using Xpath requests.
Consider that file (TPFile.xml):
If I want extracting the domains you can apply this code:
Public Sub ExtractDomain(sDomain As String)
Dim oDocSource As New MSXML2.DOMDocument
Dim oEltList As MSXML2.IXMLDOMNodeList
Dim oNode As MSXML2.IXMLDOMNode
Dim sFileName As String
Dim sRequest As String
On Error GoTo Kboom
sFileName = ThisProject.Path & "TPFile.xml"
oDocSource.Load sFileName
sRequest = "//Collection[@type='Domains']/Item[@id='" & sDomain & "']"
Set oEltList = oDocSource.selectNodes(sRequest)
If oEltList.length = 0 Then 'Not found
MsgBox "Domain not found", vbInformation + vbOKOnly, "Sorry!"
Else
For Each oNode In oEltList
MsgBox oNode.Attributes(0).Text
Next
End If
Set oDocSource = Nothing
Exit Sub
Kboom:
MsgBox Err.Number & " - " & Err.Description, vbCritical + vbOKOnly, "Kboom!"
End Sub
What is interesting is that you just have to write the good request and the rest is quite generic.
Xpath is very powerful and applied on big file can be very processor consuming.
If you want going deeper in XPath I advise following the serie of short tutorials given by the W3C School. It's a good introduction...
I attached the PcVue project.


