Soy nuevo en la programación de Access y con MSXML2.DOMDocument60, así que acepte mis disculpas si algo no es correcto. Estoy tratando de analizar un xml pero tengo problemas al cargarlo usando MSXML2.DOMDocument. La estructura del XML se muestra a continuación:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE raml SYSTEM 'raml20.dtd'>
<raml version="2.0" xmlns="raml20.xsd">
  <cmData type="actual">
    <header>
      <log dateTime="2021-03-11T13:00:47.000Z" action="created" appInfo="ActualExporter">InternalValues are used</log>
    </header>
    <managedObject class="RETU_R" version="EQMR20A_2003_002" distName="PLMN-PLMN/MRBTS-503327/EQM_R-1/APEQM_R-1/ALD_R-1/RETU_R-1" id="136127888">
      <p name="angle">20</p>
      <list name="antBandList">
        <item>
          <p name="antBeamwidth">61</p>
          <p name="antFreqBand">1</p>
          <p name="antOperGain">185</p>
        </item>
        <item>
          <p name="antBeamwidth">60</p>
          <p name="antFreqBand">2</p>
          <p name="antOperGain">185</p>
        </item>
        <item>
          <p name="antBeamwidth">61</p>
          <p name="antFreqBand">3</p>
          <p name="antOperGain">184</p>
        </item>
      </list>
      <p name="antBearing">2800</p>
      <p name="antModel">80010825-2.1_L</p>
      <p name="antSerial">DEG3535443</p>
      <list name="antlDNList">
        <p>external</p>
      </list>
      <p name="baseStationID">45118</p>
      <p name="configDN">MRBTS-503327/EQM-1/APEQM-1/ALD-9/RETU-1</p>
      <p name="installDate">240814</p>
      <p name="installerID">CRCTL</p>
      <p name="maxAngle">60</p>
      <p name="mechanicalAngle">0</p>
      <p name="minAngle">0</p>
      <p name="operationalState">1</p>
      <p name="sectorID">3U21</p>
      <p name="subunitNumber">1</p>
    </managedObject>
    
  </cmData>
</raml>

Entiendo que mi código tiene un espacio de nombres que posiblemente esté causando todos los problemas. Creé el mensaje de decodificación de error en mi vba y obtengo el siguiente error:

"No se pudo cargar el documento: C: \ Audit_DB \ Input Files \ Test1.xml
Error al cargar fue: El elemento 'raml' se usa pero no se declara en el DTD / Schema. "

¿Alguien puede aconsejarme cómo puedo omitir el espacio de nombres aquí y si hay algún problema con el código vba? El código que he creado está a continuación:

Sub XMLRead()

Dim path As String
Dim firstNameField As MSXML2.IXMLDOMNodeList
Dim lists As MSXML2.IXMLDOMNodeList
Dim raml As MSXML2.IXMLDOMElement

Dim i As Integer
Dim objXML As MSXML2.DOMDocument60
Set objXML = New MSXML2.DOMDocument60
path = "C:\Audit_DB\Input Files\Test1.xml"

objXML.SetProperty "ProhibitDTD", False

With objXML
    .async = False
    .Load path
    .SetProperty "SelectionLanguage", "XPath"
    .SetProperty "ProhibitDTD", False
    .SetProperty "SelectionNamespaces", "xmlns:raml='raml20.xsd'"
    Set nodeList = .selectNodes("//managedObject")
End With


If objXML.Load(path) Then
    Debug.Print "Success"
Else
    Debug.Print "Could not load the document: " & path
    If objXML.parseError.errorCode <> 0 Then Debug.Print "Error when loading was: " + objXML.parseError.reason
End If
    
Set xobjdetails = objXML.childNodes(0)
Set xObject = objXML.firstChild
    

Debug.Print objXML.selectNodes("//managedObject").length

End Sub
2
Muhammad Adeel Ahmed 14 mar. 2021 a las 11:27

2 respuestas

La mejor respuesta

El analizador XML está intentando respetar la declaración del tipo de documento:

<!DOCTYPE raml SYSTEM 'raml20.dtd'>

Puede proporcionar el archivo raml20.dtd para que el analizador XML pueda encontrarlo cuando cargue el XML, o puede deshabilitar la validación automática y la resolución de referencias externas (como DTD) en su DOMDocument (consulte MSDN):

With objXML
    ' ...
    .resolveExternals = False
    .validateOnParse = False
    ' ...
    .load "filepath"
End With

Ambas configuraciones deben estar deshabilitadas o la carga no se realizará correctamente. Asegúrese de configurarlos antes de intentar cargar el archivo.


Dicho esto, //managedObject no encontrará nada porque ese nodo está en el espacio de nombres raml20.xsd, al igual que todos los demás elementos de su documento.

Ya ha vinculado ese espacio de nombres al prefijo raml (con .SetProperty "SelectionNamespaces", "xmlns:raml='raml20.xsd'"), pero también debe usar el prefijo:

Debug.Print objXML.selectNodes("//raml:managedObject").length

Finalmente, su código VBA necesita una limpieza. Configura ProhibitDTD dos veces y también llama a .load más de una vez.

4
Tomalak 14 mar. 2021 a las 12:27
With objXML
    ...
    .validateOnParse = False
    ...
End With
2
artnib 14 mar. 2021 a las 11:27