У меня проблемы с синтаксическим анализом XML, возвращенного из API. Моя основная задача - получить свойства «использовано» и «ограничение» одного из узлов (с помощью xPath).
На данный момент мне даже не удается изучить все XML-дерево, поэтому я прошу помощи
Возвращенный XML выглядит так:
<?xml version="1.0" encoding="UTF-8"?>
<QueryResultRecords xmlns="http://www.xmlns.loc/sub" type="application/some.app.query+xml" href="https://my.api.call.com/query?has_cheezburger" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xmlns.loc/sub http://my.api.address.com/schema/master.xsd">
<OnlyNodeType Name="name1" link="hhttp://my.api.address.com/a5d11b73dffe" Used="240640" Limit="0" />
<OnlyNodeType Name="name2" link="http://my.api.address.com/03b11042ccd4" Used="10240" Limit="409600" />
<OnlyNodeType Name="name3" link="http://my.api.address.com/1cf43be18e2e" Used="11934947" Limit="20971520" />
</QueryResultRecords>
Я примерно понимаю, как XMLDom работает в VBA, но поискав в Интернете, мне удалось написать это, что, очевидно, не работает ...
Dim XMLDOC As MSXML2.DOMDocument60
Dim nodelist As IXMLDOMNodeList
Set XMLDOC = New MSXML2.DOMDocument60
XMLDOC.async = False
XMLDOC.validateOnParse = False
XMLDOC.Load (myhttpresponse)
Namespace = "xmlns: 'http://www.xmlns.loc/sub' "
Call XMLDOC.setProperty("SelectionNamespaces", Namespace)
Call XMLDOC.setProperty("SelectionLanguage", "XPath")
XPath = "/"
Set nodelist = XMLDOC.SelectNodes(XPath)
For i = 0 To nodelist.Length - 1
Set Node = nodelist.NextNode
Debug.Print Node.Text
Next i
Я думаю, что это проблема xml-treeing (я чего-то не понял в XMLDom?) Или проблема xmlns / xsi, и здесь я застрял полностью.
Может ли кто-нибудь помочь мне в этом?
1 ответ
Вы должны выбрать префикс пространства имен для каждого пространства имен, которое хотите использовать, даже если в XML нет префикса.
Здесь я использую sub
для обозначения пространства имен http://www.xmlns.loc/sub
.
Option Explicit
Sub Test()
Dim XmlDoc As MSXML2.DOMDocument60
Dim OnlyNodeType As MSXML2.IXMLDOMElement
Set XmlDoc = GetXml("https://my.api.call.com/query?has_cheezburger")
XmlDoc.setProperty "SelectionNamespaces", "xmlns:sub='http://www.xmlns.loc/sub'"
For Each OnlyNodeType In XmlDoc.SelectNodes("//sub:OnlyNodeType")
Debug.Print OnlyNodeType.GetAttribute("link")
Next OnlyNodeType
End Sub
Function GetXml(url As String) As MSXML2.DOMDocument60
With New MSXML2.XMLHTTP60
.Open url
.Send
Set GetXml = .responseXML
GetXml.setProperty "SelectionLanguage", "XPath"
End With
End Function
XML имеет удобные возможности пространств имен по умолчанию (объявления пространств имен без явного префикса, например xmlns="http://foo"
в отличие от xmlns:foo="http://foo"
). Этого удобного средства для XPath нет. Здесь каждая ссылка на пространство имен должна быть явной.
Пока URI пространства имен совпадает, вы можете выбрать любой префикс, который вам нравится.
Похожие вопросы
Новые вопросы
vba
Visual Basic для приложений (VBA) - это управляемый событиями объектно-ориентированный язык программирования для написания макросов, используемый для всего пакета Office, а также для других приложений. VBA не эквивалентен VB.NET или VBS; если вы работаете в Visual Studio, используйте [vb.net]. Если ваш вопрос конкретно касается программирования любого приложения MS Office, также используйте соответствующий тег: [excel], [ms-access], [ms-word], [outlook] или [ms-project].
IXMLDOMElement
. Вы также можете использоватьIXMLDOMNode
. Узел является базовым типом элемента DOM - он предлагает меньше методов и свойств, но взамен работает для всех возможных типов результатов запроса XPath. Используйте обозреватель объектов (F2 в среде разработки VBA), чтобы изучить различия между различными объектами./sub:QueryResultRecords/sub:OnlyNodeType
/sub:QueryResultRecords/sub:OnlyNodeType
и//sub:OnlyNodeType
эквивалентны, по крайней мере, для показанного вами образца XML.