So I have this pretty large XML file (40MB) that I'll have to repeatedly search. I've been schooled on the benefits of DOMDocument usage with XPath, and I thought I had it right, but I'm getting the Obj Var Not Set nonsense.
Here's the initial load...I think its loading because it delays an appropriate length of time for a 40mb file & returns no error.
Dim someElement As IXMLDOMNode
Dim xmlDoc As Object
Set xmlDoc = CreateObject("Msxml2.DOMDocument.6.0")
'<-thats a valid file name lookup
xmlDoc.Load DLookup("gsgtver", "Eramdat", "EramID = 1")
So heres where it gets dicey. I need a IXMLDOMNode to开发者_Python百科 read the parced xmlDoc object. I checked the MsXml 6.0 reference library, and I'm getting the var type when I dim (you know, the list of types that fill in for us noobs). And after I have a IXMLDOMNode set I get the list of methods (like ".text") when I try to assign, but I'm bangin on this error ..... could be a bum xpath string (although I pretty much verbatim stole it from the xpath tutorial).
sNodeName = "/Fix_Records/FixRecord/FixID[1]/Latitude"
Set someElement = xmlDoc.SelectSingleNode(sNodeName)
'yes, I dimmed xBuffer as a string up above
sBuffer = someElement.text
Incedently, I REALLY wanna do a "FixID = 'mystring' " sorta thing, but I'm doing element 1 just to get it workin. And here's the top of the xml file:
<Fix_Records xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Fix.xsd">
<!-- ******************************************************** -->
<!-- Local SITE ID : ZAB -->
<!-- Local Release Version: a082a210 -->
<!-- NASD/NADR Version : z084b210 -->
<!-- Date : 02-03-2011 19:02:56 -->
<!-- ******************************************************** -->
<FixRecord>
<FixId>00BTR</FixId>
<IcaoCode>K7</IcaoCode>
<FixType>WAYPOINT</FixType>
<FixName>BTR055100</FixName>
<FixinUs>true</FixinUs>
<IsNational>true</IsNational>
<HighPowerVor>false</HighPowerVor>
<DPositionMapData>false</DPositionMapData>
<Latitude>31170205N</Latitude>
<Longitude>089353453W</Longitude>
<AngularCorr>-0.010472</AngularCorr>
<XSpherical>0.006082693951808</XSpherical>
<YSpherical>-0.85612436871425</YSpherical>
<ZSpherical>0.516734038096893</ZSpherical>
</FixRecord>
<FixRecord>
<FixId>00N10</FixId>
<IcaoCode>MM</IcaoCode>
Thank you.....you smart people rock.
Your XPath is wrong. "/Fix_Records/FixRecord/FixID[1]/Latitude"
means you're looking for the Latitude
child element of the first FixID
child element of THE FixRecord
element.
But:
- There are many
FixRecord
elements, - For any given
FixRecord
, there is only oneFixId
child element (no need to specify[1]
), and - Most importantly,
FixId
does not have aLatitude
child element! So you're looking for something that isn't there, which is what is causing the error.- Also watch out for case sensitivity as pointed out by @James Walford.
FixId
notFixID
- Also watch out for case sensitivity as pointed out by @James Walford.
I think that what you want is: "/Fix_Records/FixRecord[1]/Latitude"
.
When you feel ready to go to the next level, try this:
"/Fix_Records/FixRecord[FixId='mystring']/Latitude"
.
If that doesn't work, there may be some namespace weirdness... Try adding xsi:
before each node specification in the Xpath:
"/xsi:Fix_Records/xsi:FixRecord[1]/xsi:Latitude"
"/xsi:Fix_Records/xsi:FixRecord[xsi:FixId='mystring']/xsi:Latitude"
Keep up the spirits, you'll get there eventually!!
You have a case sensitive problem - you're looking for FixID, you've actually got FixId. When you try and access its text you throw an exception as you have no actual object.
EDIT: as pointed out by Jean-François Corbett, your XPath is also wrong. Here is an updated Xpath solving both problems:
"/Fix_Records/FixRecord[FixId='Id you want']/Latitude"
You may also want to test if you've got a node to access, see the answer below for some tips.
Once the XML is loaded, there's still a possibility of a parsing error. This code may help you to find where the problem lies. Change it accordingly to fit your environment.
The error numbers (6666) are obviously a joke, you must have proper err numbers for your application.
Edit: Also, try parse your XML (or at least part of it) in a XML validator, like http://www.validome.org/xml/validate/.
Public Sub readXMLDoc()
Dim objXML As MSXML2.DOMDocument
Dim lookupNode As MSXML2.IXMLDOMNode
Dim vOut As Variant
Dim sNodeName As String
Dim sParseError As String
On Error GoTo ProcError
Set objXML = New MSXML2.DOMDocument
objXML.async = False
objXML.LoadXML "c:\XMLSample.xml"
If objXML Is Nothing Then Err.Raise 6666, , "Error while opening the XML file"
sParseError = objXML.parseError.reason
If Len(sParseError) > 0 Then Err.Raise 6666, , "Error while parsing the XML file: " & sParseError
sNodeName = "/Fix_Records/FixRecord/FixID[1]/Latitude"
Set lookupNode = objXML.SelectSingleNode(sNodeName)
If lookupNode.ChildNodes.Length > 0 Then
'Do your handling
End If
ProcExit:
Exit Sub
ProcError:
Debug.Assert False
Debug.Print Err.Description
Resume ProcExit
End Sub
精彩评论