子节点索引的VBA和XML快速搜索



是否有可能在没有循环的情况下提取子节点索引。

问题是具有指定的查询,无法修改到公司数据库。 脚本将以 XML 格式返回结果。

问题是,此指定的查询返回超过 10,000 个节点,每个节点有 30 个子节点。这将乘以 100。

是否有可能根据事实找到并设置节点的索引,即我使用我知道值的子节点搜索索引。

不幸的是,循环需要相当长的时间,我想让它更快一点。

总结: 我想索引节点行的位置,其中元素 1 的值 = "element1.3"。

如果此类元素不存在,则返回 false。 如果存在,则从此节点、元素 2 和元素 3 中提取。

这是一个例子,在实际代码中,我想从这一行中提取更多值。

<row>
<element1>elementone</element1>
<element2>elementtwo</element2>
<element3>elementthree</element3>
</row>
<row>
<element1>element1.2</element1>
<element2>element2.2</element2>
<element3>element3.2</element3>
</row>
<row>
<element1>element1.3</element1>
<element2>element2.3</element2>
<element3>element3.3</element3>
</row>
<row>
<element1>element1.4</element1>
<element2>element2.4</element2>
<element3>element3.4</element3>
</row>
<row>
<element1>element1.4</element1>
<element2>element2.4</element2>
<element3>element3.4</element3>
</row>

问候 公里

获取 XML 节点索引

"是否有可能根据事实定位和设置节点的索引,即我正在搜索我知道值的子节点的索引。">

由于 OP 中的问题实际上要求快速搜索节点索引,因此我演示了一种如何通过 XPath 查询获取(从 1 开始的(索引号的方法。如您所知,您可以直接通过位置号(索引号(引用每个节点名,例如通过//row[3]引用第三行。

我假设row标签紧随层次结构中的文档元素(大致相当于 Web 文档结构中的<html>标签(。

示例调用

Sub TestNodeIndex()
'[0]declare xml vars/objects
Dim xFile   As String: xFile = "rowsindex.xml"  ' <<  change to your needs
Dim xDoc    As MSXML2.DOMDocument60             ' <<  reference to Microsoft XML, v6.0
Set xDoc = New MSXML2.DOMDocument60             ' set early bound xml doc object instance to memory
'[1]load xml file
If Not xDoc.Load(ThisWorkbook.Path & "xml" & xFile) Then
MsgBox "XML File not found.", vbExclamation
Exit Sub
End If
'[2]find (first) occurrence of a row node where child node element1 has a text value of 'element1.3'
Dim xRow As MSXML2.IXMLDOMNode
Set xRow = xDoc.DocumentElement.SelectSingleNode("row[element1='" & "element1.3" & "']")
'[3]show 1-based index of found node (0 = not found)
Dim pos As Long: pos = NodeIndex(xRow, "row")
Debug.Print "Node index = " & IIf(pos, pos, "N/A")
End Sub

请注意,您可以将上述示例的部分[2..3]轻松假设单个节点选择更改为整个NodeList集的循环。

Dim xRows As MSXML2.IXMLDOMNodeList
Set xRows = xDoc.DocumentElement.SelectNodes("row[element1='" & "element1.3" & "']")
For Each xRow In xRows
Debug.Print NodeIndex(xRow, "row");
Next xRow

帮助功能NodeIndex()

Function NodeIndex(curNode As MSXML2.IXMLDOMNode, Optional ByVal tag = "row") As Long
'Purpose: get node index of current node
'Method : count preceding nodes adding current node (+1)
'a) escape if nothing found
If curNode Is Nothing Then NodeIndex = 0: Exit Function ' if no search result
'b) return node index as function result
NodeIndex = curNode.SelectNodes("preceding-sibling::" & tag).Length + 1
End Function

好的Xpath,确实似乎可以解决问题。

在我使用以下代码之前:

set row = domdoc.SelectNodes("/row[element1='" & "element1.3" & "']")

正确的应该是哪里,因为行是父节点:

set row = domdoc.SelectNodes("//row[element1='" & "element1.3" & "']")

这实际上只会返回包含我需要的子子节点的行。

最新更新