В Excel:Получить информацию о узле XML?
У меня есть сценарий, который принимает адрес, который у меня есть (в A1
), и просматривает этот адрес через GoogleAPI, который возвращает XML-документ.
Например, при использовании в качестве "123 Fake Street"
адрес возвращает следующий XML-документ:
http://maps.googleapis.com/maps/api/geocode/xml?address=123%20fake%20street&sensor=false
Как вы можете видеть (возможно удивительно), есть больше чем один "123 fake street"
там. У меня есть макрос, получающий координаты GPS от узлов Lat/Long. Как бы я захватил графство каждого? Я думал, что я мог бы использовать узел "address_component"
, но, как вы можете видеть, есть больше чем один такой узел на адрес:
Вот мой код:
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, сообщите мне!).
Спасибо за любые идеи или советы!
Edit: Вот что результат выглядит, когда я пытаюсь получить информацию от:
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
Так как вы можете видеть округ не всегда в том же «узел» - Есть ли способ объяснить это?
Ага, спасибо! Теперь, когда я могу захватить определенный индекс узла, остальная часть материала подходит ко мне, нет? Значит, похоже, что nodeIndex 5 не всегда будет округом ... Я полагаю, что нет метода «XML»/способа его определения? Я полагаю, что просто использовал VB, чтобы сделать что-то вроде: «Если в тексте nodeIndex есть * not * есть« County », тогда продолжайте искать. Else, используйте этот индекс'. – BruceWayne
Hm, я получаю ошибку' Run-time error '438' - Объект не поддерживает это свойство или метод' в строке 'county = countyNodes (i) .NodeValue' после того, как я' Set countyNodes' 'Установить countyNodes = oXMLFile.SelectSingleNode ("(/ GeocodeResponse/result/address_component) [5]/long_name/text()") ' – BruceWayne
Если графство всегда' administrator_area_level_2', вы можете искать 'address_component', который имеет этот тип, и возвращать' long_name 'от него. – Bond