VBA - Что такое синтаксис XPath для получения имен тегов

Я пытаюсь использовать макрос 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

Вы отредактировали свой вопрос после того, как я ответил на него. Вы уже прочитали это? Должен ответить на ваш вопрос.

Unhandled Exception 14.12.2020 12:00

Спасибо за ваш ответ. Да, небольшое изменение для ясности, но никаких изменений в коде. Я попытался запустить с предоставленным вами решением, и он показывает ошибку времени выполнения «91», переменная объекта или переменная блока не установлена.

onlineCake 14.12.2020 14:03

Я ожидал, что ваш код работает до сих пор. Но, кажется, это не так. Я использовал раннее связывание в своем проекте и другой код для создания экземпляра объекта. Я редактирую свой ответ сейчас.

Unhandled Exception 14.12.2020 14:16
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
1
3
895
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я предлагаю использовать раннее связывание. Итак, в вашем проекте в VBE добавьте ссылку (меню tools/references) на Microsoft XML, v6.0.

Чтобы определить атрибут и значения, вы можете использовать это:

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

Дружественный совет: неизменное выражение XPath из OP пытается обратиться к одному элементу, то есть к возможному documentElement, а не к NodeList: вместо этого попробуйте Set qXML = xmlFile.SelectNodes("//book") :-)

T.M. 14.12.2020 21:09

@T.M.: Спасибо за подсказку, но, к сожалению, я не понимаю, что ты пытаешься мне сказать. Не могли бы вы быть так добры и быть более описательным?

Unhandled Exception 15.12.2020 16:24

Посмотрите на один уровень иерархии глубже: ваш код вызывает Run time error 91 (переменная объекта или с переменной блока не установлена), поскольку ваш выбор узла проходит через несуществующие запросы пути в bookstore объекте qXML (который также является документом/верхним уровнем) и вместо этого через book элементы, которые ОП хочет проанализировать. Поэтому элемент bookstore не может отображать подузлы/атрибуты, такие как @category, title или author, а только последующие узлы book :-)

T.M. 15.12.2020 19:53

О, черт, я пропустил это. Должно быть, это произошло во время редактирования ответа. Мой тестовый код работал здесь. Спасибо за информацию. Я исправил это сейчас.

Unhandled Exception 15.12.2020 20:08
Ответ принят как подходящий

Как получить имена тегов

«Какой синтаксис XPath для получения имен тегов?»

Строго говоря, это синтаксис (XML)DOM для получения свойств .Name и/или .NodeName; 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 устарела в течение многих лет, Я бы предпочел привязку к ►MSXML2 в самой последней версии xml Microsoft XML,v6.0, например. с помощью

I. ПОЗДНЕЕ связывание (как в OP)

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

II. РАННЕЕ связывание

    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 20.12.2020 10:39

@onlineCake ... затем примените код, показанный в первой ссылке; ответ выше пытается быть как можно ближе к ОП :-)

T.M. 20.12.2020 11:16

Другие вопросы по теме