Reputation: 43
I am new in programming in Access and with MSXML2.DOMDocument60 so please accept my apologies if anything is not correct. I am trying to parse an xml but I am facing issue when loading it using MSXML2.DOMDocument. The structrue of the XML is shown below:
<?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>
I understand my code has Namespace which is possibly causing all the issues. I created the error decode Message in my vba and I get the following error :
"Could not load the document: C:\Audit_DB\Input Files\Test1.xml
Error when loading was: The element 'raml' is used but not declared in the DTD/Schema."
Can someone advise how can i skip the namespace here and if there is anything wrong with the vba code. The code I have created is below:
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
Upvotes: 2
Views: 7963
Reputation: 338426
The XML parser is trying to honor the document type declaration:
<!DOCTYPE raml SYSTEM 'raml20.dtd'>
You can either provide the raml20.dtd
file so that the XML parser can find it when it loads the XML, or you can disable the automatic validation and the resolution of external references (such as DTDs) in your DOMDocument (see MSDN):
With objXML
' ...
.resolveExternals = False
.validateOnParse = False
' ...
.load "filepath"
End With
Both settings must be disabled, or the load will not succeed. Make sure you set them before trying to load the file.
That being said, //managedObject
won't find anything because that node is in the raml20.xsd
namespace, just like all of the other elements in your document.
You've already bound that namespace to the prefix raml
(with .SetProperty "SelectionNamespaces", "xmlns:raml='raml20.xsd'"
), but you need to use the prefix, too:
Debug.Print objXML.selectNodes("//raml:managedObject").length
Finally, your VBA code needs some clean-up. You set ProhibitDTD
twice, and you call .load
more than once, too.
Upvotes: 5