获取XML节点信息?

时间:2015-08-20 15:46:42

标签: xml vba

在Excel中:

我有一个脚本,它接收我的地址(在A1中)并通过GoogleAPI查看此地址,该文件返回XML文档。

例如,使用"123 Fake Street"作为地址将返回以下XML文档:

http://maps.googleapis.com/maps/api/geocode/xml?address=123%20fake%20street&sensor=false

正如你所看到的(可能令人惊讶),那里有不止一个"123 fake street"。我让我的宏从Lat / Long节点获取GPS坐标。我怎么能抓住每个县?我以为我可以使用节点"address_component",但正如您所看到的,每个地址有多个这样的节点:

enter image description here

这是我的代码:

 Sub getXMLInfo()
    ' Adapted from  http://excel-macro.tutorialhorizon.com/vba-excel-read-data-from-xml-file/
    If Len(Cells(1, 1).Value) < 10 Then
    MsgBox ("Put an address in Cell A1!!")
    Exit Sub
    Else
     Call fnReadXMLByTags(Range("A1"))
    End If
    End Sub

...

Function fnReadXMLByTags(address As String) As String
    ' Part of of adapted from http://excel-macro.tutorialhorizon.com/vba-excel-read-data-from-xml-file/
    Dim mainWorkBook As Workbook
    Dim mainWS As Worksheet
    Dim altAddress As String
    Set mainWorkBook = ActiveWorkbook
    Set mainWS = Sheets("Sheet1")
    mainWS.Range("A:A").Clear
    Set oXMLFile = CreateObject("Microsoft.XMLDOM")

    strAddress = address ' URLEncode(Address)
    'Assemble the query string
    strQuery = "http://maps.googleapis.com/maps/api/geocode/xml?"
    strQuery = strQuery & "address=" & strAddress
    strQuery = strQuery & "&sensor=false"
    Debug.Print strQuery
    XMLFileName = strQuery

    oXMLFile.Load (XMLFileName)
    Set LatitudeNodes = oXMLFile.SelectNodes("/GeocodeResponse/result/geometry/location/lat/text()")
    Set LongitudeNodes = oXMLFile.SelectNodes("/GeocodeResponse/result/geometry/location/lng/text()")
    Set addressNodes = oXMLFile.SelectNodes("/GeocodeResponse/result/formatted_address/text()")
    Set countyNodes = oXMLFile.SelectNodes("/GeocodeResponse/result/address_component[1]/long_name/text()")
    Set misc1 = oXMLFile.SelectNodes("/GeocodeResponse/result/address_component[0]/long_name/text()")

With mainWS
    .Range("A1,B1,C1").Interior.ColorIndex = 40
    .Range("A1,B1,C1").Borders.Value = 1
    .Range("A" & 1).Value = "Lookup Address: " & address
    .Range("B" & 1).Value = "Latitude"
    .Range("C" & 1).Value = "Longitude"
    .Range("D1").Value = "Total Coordinates: " & LatitudeNodes.Length

        For i = 0 To (LatitudeNodes.Length - 1)
            Title = LatitudeNodes(i).NodeValue
            Price = LongitudeNodes(i).NodeValue
            altAddress = addressNodes(i).NodeValue


        .Range("B" & i + 2).Borders.Value = 1
        .Range("C" & i + 2).Borders.Value = 1
        .Range("B" & i + 2).Value = Title
        .Range("C" & i + 2).Value = Price
        .Range("A" & i + 2).Value = altAddress
        .Range("E" & i + 2).Value = countyNodes(i).NodeValue
        .Range("F" & i + 2).Value = "component[0] = " & misc1(i).NodeValue

    Next
    'Reading the Attributes
    Set Nodes_Attribute = oXMLFile.SelectNodes("/catalog/book")
    For i = 0 To (Nodes_Attribute.Length - 1)
        Attributes = Nodes_Attribute(i).getAttribute("id")
        .Range("A" & i + 2).Borders.Value = 1
        .Range("A" & i + 2).Value = Attributes
    Next

    Dim lastRow As Integer
    lastRow = .Cells(1, 1).End(xlDown).Row
    'https://www.google.com/maps/place//@42.8795926,-78.8762132,16z
    .Range(.Cells(2, 4), .Cells(2, 4)).Resize(lastRow - 1, 1).FormulaR1C1 = _
         "=HYPERLINK(""https://www.google.com/maps/place//@""&RC[-2]&"",""&RC[-1]&"",16z/data=!3m1!4b1!4m2!3m1!1s0x0:0x0"",""Link"")"
End With 'End the With mainWS

End Function

如您所见,我尝试在"address_component[0]"节点中执行misc1。这似乎并没有抓住第一个"address_component"。我是XML的新手,所以我为我缺乏正确的命名约定而道歉(所以如果你知道我应该查找什么XML,请告诉我!)。

感谢您的任何想法或建议!

编辑:这是我尝试从中获取信息时的结果:

Set misc1 = oXMLFile.SelectNodes("/GeocodeResponse/result/address_component[0]/long_name/text()")
Set misc2 = oXMLFile.SelectNodes("/GeocodeResponse/result/address_component[1]/long_name/text()")
Set misc3 = oXMLFile.SelectNodes("/GeocodeResponse/result/address_component[2]/long_name/text()")
Set misc4 = oXMLFile.SelectNodes("/GeocodeResponse/result/address_component[3]/long_name/text()")
Set misc5 = oXMLFile.SelectNodes("/GeocodeResponse/result/address_component[4]/long_name/text()")
        .Range("F" & i + 2).Value = misc1(i).NodeValue
    .Range("G" & i + 2).Value = misc2(i).NodeValue
    .Range("H" & i + 2).Value = misc3(i).NodeValue
    .Range("I" & i + 2).Value = misc4(i).NodeValue
    .Range("J" & i + 2).Value = misc5(i).NodeValue

enter image description here

因为你可以看到该县并不总是在同一个节点中#34; - 有什么方法可以说明这一点吗?

1 个答案:

答案 0 :(得分:1)

你很亲密。如果要访问特定节点索引,则必须在节点名称周围加上括号,然后指定索引。在你的情况下,它将是:

Set misc1 = oXMLFile.SelectSingleNode("(/GeocodeResponse/result/address_component)[5]/long_name/text()")

修改

要从long_name中选择address_component节点,其中type节点的值为administrative_area_level_2,您可以使用以下XPath:

/GeocodeResponse/result/address_component[type='administrative_area_level_2']/long_name