如何遍历 XML-nodes 并验证值是否存在?

How to loop through XML-nodes and validate if values exists?

我已经通过 API 将我的数据提取为 XML,我希望循环遍历节点(有几个相同类型的节点)并将它们添加到某些 fields/a table.

来自 XML 文件的示例:

<HistRating
  xmlns="">
  <EndrAr>2020</EndrAr>
  <EndrMnd>7</EndrMnd>
  <Rating>A</Rating>
</HistRating>
<HistRating
  xmlns="">
  <EndrAr>2019</EndrAr>
  <EndrMnd>6</EndrMnd>
  <Rating>A</Rating>
</HistRating>

我尝试了以下格式(此时我需要的 XML 在 xmlDoc xmlDoc = CreateObject("MSXML2.DOMDocument.6.0") 中的字符串中。充分意识到这不是一种真正“性感”的编写方式,但我是这个游戏的新手:

Set nodeXML = xmlDoc.getElementsByTagName("EndrAr")
Range("G1").Value = nodeXML(1).Text
Range("H1").Value = nodeXML(2).Text
Range("I1").Value = nodeXML(3).Text

Set nodeXML = xmlDoc.getElementsByTagName("EndrMnd")
Range("G2").Value = nodeXML(1).Text
Range("H2").Value = nodeXML(2).Text
Range("I2").Value = nodeXML(3).Text

Set nodeXML = xmlDoc.getElementsByTagName("Rating")
Range("G3").Value = nodeXML(1).Text
Range("H3").Value = nodeXML(2).Text
Range("I3").Value = nodeXML(3).Text

只要所有三个项目都存在,这就很好用。不幸的是,没有给出。如果它是一家新公司,即 (3) 将不存在(上面每年有一行),我想将单元格设置为空白或 No value 或其他内容。

我运行上面代码的结果:

但是如果我尝试添加第 4 行来测试如果值不存在会发生什么情况,我会得到以下结果(原因很明显)

我希望得到帮助的是:

这是从 30 个节点添加最近 X 个可用年份的会计数据(其中 X 为 4,如果没有 4,则更少)。

首先查询所有 HistRating 元素,然后遍历该集合:

Const MAX_YEARS As Long = 4
Dim ratings, rating, c As Range, i as Long

Set c= Range("A1")
Set ratings = xmlDoc.getElementsByTagName("HistRating")
For Each rating in ratings
    c.offset(0, i) = rating.getElementsByTagName("EndrAr")(0).Text
    c.offset(1, i) = rating.getElementsByTagName("EndrMnd")(0).Text
    c.offset(2, i) = rating.getElementsByTagName("Rating")(0).Text
    i = i + 1
    If i >= MAX_YEARS Then Exit For 'exit if processed enough nodes
Next rating

您可以使用错误捕获功能。请注意,在下面的代码中,我们选择不使用返回的布尔值。

Dim myTest as String
.
.
TryReadingXmlNode nodeXML,1, myText
Range("G1").Value = myText
.   
.

Public Function TryReadingXmlNode(ByVal ipNode as object, ByVal ipIndex as Long, ByRef opText as string) as boolean

    On Error Resume Next
    opText=ipNode.Item(ipIndex).Text
    TryReadingXmlNode=Len(opText)>0
    If err.number>0 then opText="NoValue"
    on Error Goto 0
 
End Function