首页 > 解决方案 > VBA 中的 XML 和 XPath 处理

问题描述

我正在尝试使用 VBA 将 XML 解析为电子表格,但由于某种原因,我无法使用 XPath 访问我想要的节点,我的 XML 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<cteProc xmlns="http://www.somesite.com" versao="3.00">
 <CTe xmlns="http://www.somesite.com">
  <infCte Id="an id" versao="3.00">
    <ide>
     <cUF>23</cUF>
     <cCT>00000557</cCT>
     <CFOP>6932</CFOP>
     <natOp>some text </natOp>
     <mod>57</mod>
    </ide>
    <compl>
      <xObs>TEXT</xObs>
    </compl>
  </infCte>
 </CTe>
</cteProc>

我试图至少到达ide节点,所以我可以遍历其余节点并获取我想要的信息。

我的代码如下所示:

Public Sub parseXml()

Dim oXMLFile As MSXML2.DOMDocument60
Dim nodes As MSXML2.IXMLDOMNodeList

path2 = "C:\Users\me\Desktop\adoc.xml"

Set oXMLFile = New MSXML2.DOMDocument60

oXMLFile.Load (path2)

Set nodes = oXMLFile.DocumentElement.SelectNodes("/CTe")

所以我试图打印节点的长度,我得到了这个:

debug.print nodes.length

> 0

如果我这样循环:

Public Sub parseXml()

Dim oXMLFile As MSXML2.DOMDocument60
Dim nodes As MSXML2.IXMLDOMNodeList
Dim node As MSXML2.IXMLDOMNode

path2 = "C:\Users\me\Desktop\adoc.xml"

Set oXMLFile = New MSXML2.DOMDocument60

oXMLFile.Load (path2)


Set nodes = oXMLFile.DocumentElement.ChildNodes


For Each node In nodes
    Debug.Print node.BaseName
Next node

我明白了:

> CTe

所以,如果我做一个巨大的循环,我可以获得我想要的信息,但我认为必须有一个更简单的解决方案。

标签: excelxmlvba

解决方案


由于您XML使用命名空间,因此XPath还需要处理命名空间。

以下适用于我使用您的XML

Public Sub parseXml()

 Dim oXML As MSXML2.DOMDocument60
 Dim oNodes As MSXML2.IXMLDOMNodeList
 Dim oItem As MSXML2.IXMLDOMNode
 Dim path2 As String
 
 path2 = "P:\adoc.xml"

 Set oXML = New MSXML2.DOMDocument60

 oXML.Load path2
 oXML.setProperty "SelectionLanguage", "XPath"
 oXML.setProperty "SelectionNamespaces", "xmlns:ssc=""http://www.somesite.com"""
 
 Set oNodes = oXML.DocumentElement.SelectNodes("ssc:CTe")
 
 For Each oItem In oNodes
  MsgBox oItem.nodeName
 Next

End Sub

那里使用

oXMLFile.setProperty "SelectionNamespaces", "xmlns:ssc=""http://www.somesite.com"""

ssc我为命名空间定义了一个前缀

http://www.somesite.com.

这是我自己scc选择(一些网站。com )。这个前缀是in方法正常工作所必需的。XPATHselectNodes

如果您不想定义命名空间,则必须使用local-name()XPath 函数。例如:

Set oNodes = oXML.DocumentElement.SelectNodes("*[local-name() = 'CTe']")

推荐阅读