Je suis nouveau dans la programmation dans Access et avec MSXML2.DOMDocument60 alors veuillez accepter mes excuses si quelque chose n'est pas correct. J'essaie d'analyser un XML mais je suis confronté à un problème lors du chargement à l'aide de MSXML2.DOMDocument. La structure du XML est indiquée ci-dessous:

<?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>

Je comprends que mon code a un espace de noms qui est peut-être à l'origine de tous les problèmes. J'ai créé le message de décodage d'erreur dans mon vba et j'obtiens l'erreur suivante:

"Impossible de charger le document: C: \ Audit_DB \ Input Files \ Test1.xml
Erreur lors du chargement: L'élément 'raml' est utilisé mais pas déclaré dans la DTD / Schéma. "

Quelqu'un peut-il conseiller comment puis-je ignorer l'espace de noms ici et s'il y a quelque chose qui ne va pas avec le code vba. Le code que j'ai créé est ci-dessous:

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 mars 2021 à 11:27

2 réponses

Meilleure réponse

L'analyseur XML tente d'honorer la déclaration de type de document:

<!DOCTYPE raml SYSTEM 'raml20.dtd'>

Vous pouvez soit fournir le fichier raml20.dtd pour que l'analyseur XML puisse le trouver lorsqu'il charge le XML, soit désactiver la validation automatique et la résolution des références externes (telles que les DTD) dans votre DOMDocument (voir MSDN):

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

Les deux paramètres doivent être désactivés, sinon le chargement échouera. Assurez-vous de les définir avant d'essayer de charger le fichier.


Cela étant dit, //managedObject ne trouvera rien car ce nœud est dans l'espace de noms raml20.xsd, tout comme tous les autres éléments de votre document.

Vous avez déjà lié cet espace de noms au préfixe raml (avec .SetProperty "SelectionNamespaces", "xmlns:raml='raml20.xsd'"), mais vous devez également utiliser le préfixe:

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

Enfin, votre code VBA a besoin d'un nettoyage. Vous définissez ProhibitDTD deux fois et vous appelez .load plus d'une fois également.

4
Tomalak 14 mars 2021 à 12:27
With objXML
    ...
    .validateOnParse = False
    ...
End With
2
artnib 14 mars 2021 à 11:27