MsXml-DOMDocument过程的IXMLDOMNode上的“对象变量未设置”

时间:2011-03-25 12:10:35

标签: xml vba xpath access-vba

所以我有这个非常大的XML文件(40MB),我将不得不重复搜索。我已经接受过使用XPath的DOMDocument使用的好处,我认为我做对了,但我得到的是Obj Var Not Set废话。

这是初始加载......我认为它的加载是因为它延迟了40mb文件的适当时间长度。没有错误。

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") 

所以它会变得冒险。我需要一个IXMLDOMNode来读取parced的xmlDoc对象。我检查了MsXml 6.0参考库,当我昏暗时我得到了var类型(你知道,为我们填充的类型列表)。 在我有一个IXMLDOMNode设置之后,当我尝试分配时,我得到了方法列表(比如“.text”),但是我对这个错误感到沮丧.....可能是一个bum xpath字符串(虽然我差不多verbatim从xpath教程中偷走了它。

sNodeName = "/Fix_Records/FixRecord/FixID[1]/Latitude"
Set someElement = xmlDoc.SelectSingleNode(sNodeName)

'yes, I dimmed xBuffer as a string up above
sBuffer = someElement.text 

很明显,我真的想做一个“FixID ='mystring'”sorta事情,但我正在做元素1只是为了让它工作。 这是xml文件的顶部:

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

谢谢.....你聪明的人摇滚。

3 个答案:

答案 0 :(得分:2)

你的XPath错了。 "/Fix_Records/FixRecord/FixID[1]/Latitude"表示您正在查找Latitude元素的第一个FixID子元素的FixRecord子元素。

可是:

  • 有许多FixRecord元素,
  • 对于任何给定的FixRecord,只有一个FixId子元素(无需指定[1]),
  • 最重要的是,FixId没有Latitude子元素!所以你正在寻找不存在的东西,这就是造成错误的原因。
    • 同时注意@James Walford指出的区分大小写。 FixId不是FixID

我认为你想要的是:"/Fix_Records/FixRecord[1]/Latitude"

当你准备好进入下一个级别时,试试这个:

"/Fix_Records/FixRecord[FixId='mystring']/Latitude"

如果这不起作用,可能会有一些命名空间怪异...尝试在Xpath中的每个节点规范之前添加xsi:

"/xsi:Fix_Records/xsi:FixRecord[1]/xsi:Latitude"
"/xsi:Fix_Records/xsi:FixRecord[xsi:FixId='mystring']/xsi:Latitude"

保持精神,你最终会到达那里!!

答案 1 :(得分:1)

你有一个区分大小写的问题 - 你正在寻找FixID,你实际上已经得到了FixId。 当您尝试访问其文本时,您会抛出异常,因为您没有实际对象。

编辑:正如Jean-FrançoisCorbett所指出的,你的XPath也是错误的。这是一个更新的Xpath解决了这两个问题:

"/Fix_Records/FixRecord[FixId='Id you want']/Latitude"

您可能还想测试您是否有要访问的节点,请参阅下面的答案以获取一些提示。

答案 2 :(得分:0)

加载XML后,仍有可能出现解析错误。此代码可以帮助您找到问题所在。根据您的环境进行相应更改。

错误号码(6666)显然是一个笑话,你的应用程序必须有正确的错误号码。

编辑另外,请尝试在XML验证程序中解析XML(或至少部分内容),例如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