【问题标题】:VBA - What's The XPath Syntax To Get Tag NamesVBA - 获取标签名称的 XPath 语法是什么
【发布时间】:2020-12-14 07:07:08
【问题描述】:

我正在尝试使用 VBA 宏来解析 XML 文件。具有以下结构:

  <bookstore>
  <book category="children">
    <title>Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="web">
    <title>Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
  </book>
  </bookstore>

如何使用元素标签枚举输出及其对应值,如下所示?

book | category | children
title | harry potter
author | J K. Rowling
...

我的代码如下:

Set xmlFile = CreateObject("Microsoft.XMLDOM")
xmlFile.Load (file)
Set qXML = xmlFile.SelectNodes("/bookstore")
For i = 0 To qXML.Length - 1
  Debug.Print CStr(qXML(i).Text)
Next i

【问题讨论】:

  • 您在我回答后编辑了您的问题。你已经读过了吗?应该回答你的问题。
  • 感谢您的回复。是的,为了清晰起见略有变化,但根本没有改变代码。我尝试使用您提供的解决方案运行,它显示运行时错误“91”、对象变量或未设置块变量。
  • 我预计您的代码目前正在运行。但它似乎不是这样的。我在我的项目中使用了早期绑定,并使用了不同的代码来实例化对象。我现在编辑我的答案。

标签: excel vba xpath xmldom


【解决方案1】:

如何获取标签名称

“获取标签名称的 XPath 语法是什么?”

严格来说,获取.Name 和/或.NodeName 属性是(XML)DOM 语法; XMLDOM(文档对象模型) 是一个跨平台且独立于语言的接口,将文档视为树结构并允许以编程方式访问树。

您可以使用 XPath 表达式的特殊语法(例如 "/bookstore/book/title")来处理分层 xml 文档结构中的任何逻辑部分。

因此,接近您的 OP 的解决方案是:

Option Explicit             ' declaration head of your code module

Sub ExampleCall()
    Dim file As String: file = ThisWorkbook.Path & "\xml\bookstore.xml"
    Dim xmlFile As Object
    Set xmlFile = CreateObject("Microsoft.XMLDOM")
    If xmlFile.Load(file) Then
        Dim qXML As Object
        Set qXML = xmlFile.DocumentElement.SelectNodes("book")
        Dim q As Object
        For Each q In qXML
            Dim cnt As Long: cnt = cnt + 1
            Debug.Print Format(cnt, "--- 000 ---")
            Debug.Print q.Attributes(0).Name, "|" & q.Attributes(0).Text
            Dim i As Long
            For i = 0 To q.ChildNodes.Length - 1
                Debug.Print q.ChildNodes(i).nodeName, "|" & q.ChildNodes(i).Text
            Next
        Next
    End If
End Sub

VBE 的即时窗口中的结果

--- 01 ---
category      |children
title         |Harry Potter
author        |J K. Rowling
year          |2005
price         |29.99
--- 02 ---
category      |web
title         |Learning XML
author        |Erik T. Ray
year          |2003
price         |39.95

旁注

Microsoft.XMLDOM 已被弃用多年, 我更喜欢在最新的 xml 版本 Microsoft XML,v6.0 中绑定到 ►MSXML2,例如通过

我。后期绑定(如 OP)

    Dim xDoc As Object
    Set xDoc = CreateObject("MSXML2.DOMDocument.6.0")

二。早期绑定

    Dim xDoc As MSXML2.DOMDocument60     ' *) whereas MSXML2.DOMDocument (=old version 3.0)
    Set xDoc = New MSXML2.DOMDocument60  ' mind the missing point in digits

旁注:OP 使用对象变量XMLFile 而不是xDoc

注意默认情况下,在没有明显版本控制的情况下引用 DOMDocument 将在内部绑定到 3.0 (6.0之前的最后一个稳定版本,其他版本都弃用了)。

更多链接

【讨论】:

  • 如果有嵌套节点怎么办?
  • @onlineCake ...然后应用第一个链接中显示的代码;上面的答案试图尽可能接近 OP :-)
【解决方案2】:

我建议使用早期绑定。 因此,在您的 VBE 项目中添加对Microsoft XML, v6.0 的引用(菜单tools/references)。

要确定属性和值,您可以使用:

Dim xmlFile As MSXML2.DOMDocument60
Set xmlFile = New MSXML2.DOMDocument60

xmlFile.Load file

Dim qXML As MSXML2.IXMLDOMNodeList
Set qXML = xmlFile.SelectNodes("/bookstore/book")

Dim index As Long
For index = 0 To qXML.Length - 1
    Debug.Print qXML(index).SelectSingleNode("@category").Text
    Debug.Print qXML(index).SelectSingleNode("title").Text
    Debug.Print qXML(index).SelectSingleNode("author").Text
Next index

【讨论】:

  • 友情提示:来自 OP 的未更改 XPath 表达式尝试处理 single 元素,即可能的 documentElement 而不是 NodeList:尝试Set qXML = xmlFile.SelectNodes("//book") 代替 :-)
  • @T.M.:谢谢你的提示,但不幸的是我不明白你想告诉我什么。你会这么善良,更描述性吗?
  • 更深入地查看一个层次结构级别:您的代码引发了Run time error 91 (对象变量或未设置块变量),因为您的节点选择循环通过不存在的路径查询bookstore 对象 qXML (也是 documentElement/顶级),而是通过 OP 想要分析的 book 元素。因此bookstore 元素不能显示子节点/属性,如@categorytitleauthor,只能显示后续的book 节点:-)
  • 哦,该死的,我错过了那个。这一定是在编辑答案时发生的。我的测试代码在这里运行。谢谢(你的)信息。我现在更正了。
猜你喜欢
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多