如何导航含多个同名Item节点的XML并访问所有兄弟节点?
问题:VB访问XML时仅能获取第一个- 节点数据的解决办法
场景说明
有一个不可修改的XML文件,结构如下:
<root> <Item> Data 1 (some data nodes at variable depth) </Item> <Item> Data 2 </Item> .... <Item> Data N </Item> </root>
使用VB代码访问该XML时,始终只能获取第一个<Item>节点的数据,尝试多种方式后仍无法访问其他兄弟节点,相关VB代码片段如下:
Set rst2 = dbs.OpenRecordset(strSQL, dbOpenDynaset) rst2.MoveFirst If xmlDoc.Load(path) Then Set oNodeList = xmlDoc.getElementsByTagName("Item") For i = 0 To oNodeList.Length - 1 Set oNode = oNodeList.Item(i) ' can I index the list like this ? rst2.Edit ' a DAO record set (it works OK) rst1.MoveFirst Do While Not rst1.EOF xp = rst1("XPath") ' the path under oNode Set oNode1 = oNodeList(1).selectSingleNode(xp) sVal = oNode1.Text 'Here I always get the data from Data 1 If Len(sVal) > 0 Then rst2(rst1("FieldName")) = sVal End If rst1.MoveNext Loop rst2.Update rst2.MoveNext Next i Else MsgBox "Unable to load XML file." End If
问题根源
代码核心错误是固定使用oNodeList(1)调用selectSingleNode,而非循环中当前迭代的oNode节点。这导致每次都从同一个固定的<Item>节点获取数据,自然只能拿到第一条内容。
修正后的代码
将循环内的关键行改为使用当前的oNode节点,并增加空值判断避免报错:
Set rst2 = dbs.OpenRecordset(strSQL, dbOpenDynaset) rst2.MoveFirst If xmlDoc.Load(path) Then Set oNodeList = xmlDoc.getElementsByTagName("Item") For i = 0 To oNodeList.Length - 1 Set oNode = oNodeList.Item(i) ' 此索引方式正确,IXMLDOMNodeList.Item支持从0开始的索引 rst2.Edit rst1.MoveFirst Do While Not rst1.EOF xp = rst1("XPath") ' 修正:基于当前循环的oNode节点查找子节点 Set oNode1 = oNode.selectSingleNode(xp) ' 增加空值判断,防止XPath找不到节点时报错 If Not oNode1 Is Nothing Then sVal = oNode1.Text If Len(sVal) > 0 Then rst2(rst1("FieldName")) = sVal End If End If rst1.MoveNext Loop rst2.Update rst2.MoveNext Next i Else MsgBox "无法加载XML文件。" End If
额外说明
oNodeList.Item(i)的用法是正确的,IXMLDOMNodeList支持通过Item方法传入从0开始的索引获取对应节点,也可直接简写为oNodeList(i)(VB集合的默认属性为Item)。- 新增的
If Not oNode1 Is Nothing Then判断,可避免当XPath无法匹配到节点时触发运行时错误。
内容的提问来源于stack exchange,提问作者Islander
相关产品推荐
相关产品推荐

