Results 1 to 3 of 3
  1. #1
    RMittelman is offline Advanced
    Windows 10 Access 2016
    Join Date
    Dec 2010
    Location
    Simi Valley, CA
    Posts
    211

    Access VBA XML Code not Working with MSXML 6

    I recently upgraded my development PC and some of the XML functionality stopped working properly. I was using MSXML2 on the old PC. That wasn't available on the new PC, just MSXML3 and MSXML6, so I decided to move to the version 6. Here is a snippet of some code from an XML class I wrote:
    Code:
    Dim xDoc    As MSXML2.DOMDocument60
    Dim root    As MSXML2.IXMLDOMNode
    Dim m_node  As MSXML2.IXMLDOMNode
    
    Public Function LoadXmlFile(fileName As String) As Boolean
    
        LoadXmlFile = False
        
        On Error Resume Next
        Set xDoc = New DOMDocument60 ' MSXML2.DOMDocument
        If Err.Number = 0 Then
            xDoc.async = False
            xDoc.validateOnParse = False
            xDoc.Load (fileName)
            If Err.Number <> 0 Then
                m_error = Err.Description
                Set xDoc = Nothing
                Set root = Nothing
            Else
                m_error = ""
                Set root = xDoc.DocumentElement
                LoadXmlFile = True
            End If
        End If
        On Error GoTo 0
    
    End Function
    
    Public Function GetNodeByName(Name As String) As Boolean
    
        GetNodeByName = False
        If Not xDoc Is Nothing Then
            On Error Resume Next
            Set m_node = xDoc.SelectSingleNode("//" & Name)
            GetNodeByName = Not m_node Is Nothing
            m_error = IIf(Err.Number = 0, "", Err.Description)
            On Error GoTo 0
        End If
    
    End Function
    Here is some of my calling code:
    Code:
        Const xml_file  As String = "C:\ProgramData\EDESuite\Year{year}\EDExpress for Windows\EDESuite.xml"
    
        Dim oXml        As New clsXML
        Dim fso         As New FileSystemObject
        Dim valName     As String
        Dim xmlFile     As String
        Dim isOK        As Boolean
        
        valName = ""
        xmlFile = Replace$(xml_file, "{year}", awdYear)
        isOK = fso.FileExists(xmlFile)
        If isOK Then
            isOK = oXml.LoadXmlFile(xmlFile)
            If isOK Then isOK = oXml.GetNodeByName("Database")
            If isOK Then
                valName = oXml.GetNodeAttributeValue("Path")
                isOK = valName <> "~"
            End If
        Else
            MsgBox "EDESuite.xml file not found." & vbCrLf & "Please contact Tech Support", vbExclamation, "Error"
        End If
    So this statement: isOK = oXml.LoadXmlFile(xmlFile)
    works, and the XML file loads fine. Here is the xml from the file after executing the above statement



    Code:
    <?xml version="1.0"?><EDESuite xmlns="http://tempuri.org/EDESuiteAppSettings.xsd">
        <Database Path="M:\FedConnect\Schools\UAV\Expres19.accdb"></Database>
        <Executable Path="C:\Program Files (x86)\EDESuite\EDExpress for Windows 2018-2019"></Executable>
        <InstalledModules>
            <Module Name="ApplicationProcessing" Load="true"></Module>
            <Module Load="false" Name="COD"></Module>
            <Module Load="false" Name="DirectLoan"></Module>
            <Module Name="FinancialAidShoppingSheet" Load="true"></Module>
            <Module Name="Global" Load="true"></Module>
            <Module Name="Packaging" Load="true"></Module>
            <Module Load="false" Name="Pell"></Module>
            <Module Load="false" Name="TEACH"></Module>
        </InstalledModules>
    </EDESuite>
    The problem occurs with the statement: If isOK Then isOK = oXml.GetNodeByName("Database")
    When I step through the GetNodeByName method, the statement: Set m_node = xDoc.SelectSingleNode("//" & Name)
    returns Nothing for m_node.

    This has always worked in he past, but now it doesn't. The x-path seems to be right. Is there some difference with MSXML6 that I am missing?

    Thanks...

  2. #2
    RMittelman is offline Advanced
    Windows 10 Access 2016
    Join Date
    Dec 2010
    Location
    Simi Valley, CA
    Posts
    211
    I noticed that if I switch the reference to MSXML3 it seems to work again. I'd still like to know why the same code works on MSXML3 but not MSXML6...

  3. #3
    RMittelman is offline Advanced
    Windows 10 Access 2016
    Join Date
    Dec 2010
    Location
    Simi Valley, CA
    Posts
    211
    I seem to have found the solution. According to this article: https://docs.microsoft.com/en-us/pre...des-not-return,
    MSXML6 has a higher level of security, and if the XML file has a default namespace you need to tell the document object about it by adding a namespace prefix.

    This code seems to work now:
    Code:
    Dim m_hasNamespace As Boolean
    
    Public Function LoadXmlFile(fileName As String) As Boolean
    
        Dim isOK    As Boolean
        
        LoadXmlFile = False
        
        On Error Resume Next
        Set xDoc = New MSXML2.DOMDocument60
    
    
        If Err.Number = 0 Then
            
            xDoc.async = False
            xDoc.validateOnParse = False
            xDoc.Load (fileName)
            If Err.Number <> 0 Then
                
                m_error = Err.Description
                Set xDoc = Nothing
                Set root = Nothing
                
            Else
                
                If FixNamespace Then
                    m_error = ""
                    Set root = xDoc.DocumentElement
                    LoadXmlFile = True
                Else
                    m_error = "Couldn't add namespace prefix"
                End If
    
            End If
        End If
        On Error GoTo 0
    
    
    End Function
    
    Private Function FixNamespace() As Boolean
    
        FixNamespace = False
        On Error Resume Next
        m_hasNamespace = Nz(xDoc.namespaces(0), "") > ""
        If m_hasNamespace Then
            xDoc.SetProperty "SelectionNamespaces", "xmlns:doc='" & xDoc.namespaces(0) & "'"
        End If
        FixNamespace = Err.Number = 0
    
    End Function
    Then I modified the code the GetNodeByName function as follows:
    Code:
    Public Function GetNodeByName(Name As String) As Boolean
    
        GetNodeByName = False
        If Not xDoc Is Nothing Then
            On Error Resume Next
            Set m_node = xDoc.SelectSingleNode("//" & IIf(m_hasNamespace, "doc:", "") & Name)
            GetNodeByName = Not m_node Is Nothing
            m_error = IIf(Err.Number = 0, "", Err.Description)
            On Error GoTo 0
        End If
    
    
    End Function
    Not sure how to adapt this for an XML file with multiple default namespaces, but for now it seems to work fine.

Please reply to this thread with any new information or opinions.

Similar Threads

  1. Replies: 28
    Last Post: 01-24-2018, 05:14 PM
  2. Replies: 2
    Last Post: 05-14-2017, 10:07 AM
  3. Replies: 1
    Last Post: 12-27-2014, 12:38 PM
  4. Replies: 2
    Last Post: 06-28-2013, 12:58 PM
  5. Login ID Code for Access 2007 not working
    By amangupts in forum Programming
    Replies: 25
    Last Post: 07-07-2011, 01:28 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums