บริการบนเว็บของ Google Maps Platform คือชุดอินเทอร์เฟซ HTTP สำหรับบริการของ Google ซึ่งให้ข้อมูลทางภูมิศาสตร์สำหรับแอปพลิเคชันแผนที่ของคุณ
คู่มือนี้อธิบายแนวทางปฏิบัติทั่วไปบางอย่างที่เป็นประโยชน์ในการตั้งค่า บริการเว็บ คำขอและการประมวลผลการตอบกลับของบริการ โปรดดูเอกสารประกอบทั้งหมดของ Directions API (เดิม) ในคู่มือสำหรับนักพัฒนาซอฟต์แวร์
เว็บเซอร์วิสคืออะไร
บริการเว็บของ Google Maps Platform เป็นอินเทอร์เฟซสำหรับขอข้อมูล Maps API จาก บริการภายนอกและใช้ข้อมูลภายในแอปพลิเคชัน Maps บริการเหล่านี้ออกแบบมาเพื่อใช้ร่วมกับแผนที่ตามข้อจำกัดด้านใบอนุญาตในข้อกำหนดในการให้บริการของ Google Maps Platform
บริการบนเว็บของ Maps API ใช้คำขอ HTTP(S) ไปยัง URL ที่เฉพาะเจาะจง โดยส่งพารามิเตอร์ URL และ/หรือข้อมูล POST ในรูปแบบ JSON เป็นอาร์กิวเมนต์ไปยังบริการ โดยทั่วไป บริการเหล่านี้จะแสดงข้อมูลใน ส่วนเนื้อหาการตอบกลับเป็น JSON หรือ XML เพื่อให้แอปพลิเคชันของคุณทำการแยกวิเคราะห์ และ/หรือประมวลผล
โดยทั่วไปแล้ว คำขอ Directions API (เดิม) มักจะมีรูปแบบดังนี้
https://maps.googleapis.com/maps/api/directions/output?parameters
โดย output ระบุรูปแบบการตอบกลับ (โดยปกติคือ
json หรือ xml)
หมายเหตุ: แอปพลิเคชัน Directions API (เดิม) ทั้งหมดต้องมีการตรวจสอบสิทธิ์ ดูข้อมูลเพิ่มเติมเกี่ยวกับข้อมูลเข้าสู่ระบบสำหรับการตรวจสอบสิทธิ์
การเข้าถึง SSL/TLS
ต้องใช้ HTTPS สำหรับคำขอทั้งหมดของแพลตฟอร์ม Google Maps ที่ใช้คีย์ API หรือมีข้อมูลผู้ใช้ คำขอที่ส่งผ่าน HTTP ซึ่งมีข้อมูลที่ละเอียดอ่อนอาจถูกปฏิเสธ
การสร้าง URL ที่ถูกต้อง
คุณอาจคิดว่า URL ที่ "ถูกต้อง" นั้นชัดเจนในตัวอยู่แล้ว แต่
ในความเป็นจริงแล้วไม่ใช่ ตัวอย่างเช่น URL ที่ป้อนในแถบที่อยู่ของเบราว์เซอร์อาจมีอักขระพิเศษ (เช่น "上海+中國") เบราว์เซอร์ต้องแปลอักขระเหล่านั้นเป็นการเข้ารหัสอื่นภายในก่อนที่จะส่ง
ในทำนองเดียวกัน โค้ดใดๆ ที่สร้างหรือยอมรับอินพุต UTF-8
อาจถือว่า URL ที่มีอักขระ UTF-8 เป็น "ใช้ได้" แต่ก็จะต้อง
แปลอักขระเหล่านั้นก่อนที่จะส่งไปยังเว็บเซิร์ฟเวอร์ด้วย
กระบวนการนี้เรียกว่า
URL-encoding หรือ percent-encoding
อักขระพิเศษ
เราต้องแปลอักขระพิเศษเนื่องจาก URL ทั้งหมดต้องเป็นไปตามไวยากรณ์ที่ระบุโดยข้อกำหนดของตัวระบุ ทรัพยากรแบบ สม่ำเสมอ (URI) ซึ่งหมายความว่า URL ต้องมีเฉพาะอักขระ ASCII ที่เป็นเซ็ตย่อยพิเศษ ได้แก่ สัญลักษณ์ตัวอักษรและตัวเลขที่คุ้นเคย และอักขระที่สงวนไว้บางตัวสำหรับใช้เป็นอักขระควบคุม ภายใน URL ตารางนี้สรุปอักขระดังกล่าว
| ตั้งค่า | อักขระ | การใช้งาน URL |
|---|---|---|
| ตัวอักษรและตัวเลขคละกัน | ก ข ค ง จ ฉ ช ซ ฌ ญ ฎ ฏ ฐ ฑ ฒ ณ ด ต ถ ท ธ น บ ป ผ พ ภ ม ย ร ล ว ศ ษ ส ห ฬ อ ฮ 0 1 2 3 4 5 6 7 8 9 | สตริงข้อความ การใช้รูปแบบ (http) พอร์ต (8080) ฯลฯ |
| ไม่ได้จอง | - _ . ~ | สตริงข้อความ |
| จองแล้ว | ! * ' ( ) ; : @ & = + $ , / ? % # [ ] | อักขระควบคุมและ/หรือสตริงข้อความ |
เมื่อสร้าง URL ที่ถูกต้อง คุณต้องตรวจสอบว่า URL นั้นมีเฉพาะอักขระที่แสดงในตาราง เท่านั้น การปรับ URL ให้ใช้ชุดอักขระนี้มักจะ ทำให้เกิดปัญหา 2 อย่าง ได้แก่ ปัญหาการละเว้นและปัญหาการแทนที่
- อักขระที่คุณต้องการจัดการอยู่นอกชุดอักขระ
ที่ตั้งไว้ข้างต้น เช่น อักขระในภาษาต่างประเทศ
เช่น
上海+中國ต้องได้รับการเข้ารหัสโดยใช้อักขระ ด้านบน ตามธรรมเนียมที่นิยมใช้กัน ช่องว่าง (ซึ่งไม่อนุญาตให้ใช้ภายใน URL) มักจะแสดงโดยใช้อักขระบวก'+'ด้วย - อักขระจะอยู่ในชุดด้านบนเป็นอักขระที่สงวนไว้
แต่ต้องใช้ตามตัวอักษร
เช่น
?ใช้ภายใน URL เพื่อระบุจุดเริ่มต้นของสตริงคำค้นหา หากต้องการใช้สตริง "? and the Mysterions" คุณจะต้องเข้ารหัสอักขระ'?'
อักขระทั้งหมดที่จะเข้ารหัส URL จะได้รับการเข้ารหัส
โดยใช้'%'และค่าฐานสิบหก 2 อักขระ
ที่สอดคล้องกับอักขระ UTF-8 เช่น
上海+中國 ใน UTF-8 จะได้รับการเข้ารหัส URL เป็น
%E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B สตริง
? and the Mysterians จะได้รับการเข้ารหัส URL เป็น
%3F+and+the+Mysterians หรือ %3F%20and%20the%20Mysterians
อักขระทั่วไปที่ต้องเข้ารหัส
อักขระทั่วไปบางส่วนที่ต้องเข้ารหัสมีดังนี้
| อักขระที่ไม่ปลอดภัย | ค่าที่เข้ารหัส |
|---|---|
| Space | %20 |
| " | %22 |
| < | %3C |
| > | %3E |
| # | %23 |
| % | %25 |
| | | %7C |
บางครั้งการแปลง URL ที่คุณได้รับจากข้อมูลที่ผู้ใช้ป้อนอาจเป็นเรื่อง ยาก เช่น ผู้ใช้อาจป้อนที่อยู่เป็น "5th&Main St." โดยทั่วไป คุณควรสร้าง URL จากส่วนต่างๆ โดยถือว่า อินพุตของผู้ใช้เป็นอักขระตามตัว
นอกจากนี้ URL ยังมีความยาวไม่เกิน 16384 ตัวสำหรับเว็บเซอร์วิสทั้งหมดของ Google Maps Platform และเว็บ API แบบคงที่ สำหรับบริการส่วนใหญ่ คุณแทบจะไม่ต้องกังวลเรื่องจำนวนอักขระสูงสุดนี้ อย่างไรก็ตาม โปรดทราบว่าบริการบางอย่างมีพารามิเตอร์หลายรายการที่อาจส่งผลให้ URL ยาว
การใช้ Google APIs อย่างสุภาพ
ไคลเอ็นต์ API ที่ออกแบบมาไม่ดีอาจทำให้เกิดโหลดมากกว่าที่จำเป็นทั้งบนอินเทอร์เน็ตและเซิร์ฟเวอร์ของ Google ส่วนนี้มีแนวทางปฏิบัติแนะนำบางส่วนสำหรับไคลเอ็นต์ของ API การปฏิบัติตามแนวทางปฏิบัติแนะนำเหล่านี้จะช่วยให้คุณหลีกเลี่ยงไม่ให้แอปพลิเคชันถูกบล็อกเนื่องจากการละเมิด API โดยไม่ตั้งใจ
Exponential Backoff
ในบางกรณีที่พบไม่บ่อยนัก อาจเกิดข้อผิดพลาดในการแสดงผลคำขอ คุณอาจได้รับรหัสการตอบกลับ HTTP 4XX หรือ 5XX หรือการเชื่อมต่อ TCP อาจล้มเหลวระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ของ Google บ่อยครั้งที่การลองส่งคำขออีกครั้งก็คุ้มค่า เนื่องจากคำขอติดตามอาจสำเร็จเมื่อคำขอเดิมไม่สำเร็จ อย่างไรก็ตาม สิ่งสำคัญคือคุณไม่ควร วนซ้ำเพื่อส่งคำขอไปยังเซิร์ฟเวอร์ของ Google ลักษณะการวนซ้ำนี้อาจทำให้เครือข่ายระหว่างไคลเอ็นต์กับ Google ทำงานหนักเกินไป ซึ่งจะส่งผลให้เกิดปัญหาสำหรับหลายฝ่าย
แนวทางที่ดีกว่าคือการลองอีกครั้งโดยเพิ่มความล่าช้าระหว่างการลองแต่ละครั้ง โดยปกติแล้ว ความล่าช้าจะเพิ่มขึ้นตามปัจจัยคูณในแต่ละครั้ง ซึ่งเป็นแนวทางที่เรียกว่า Exponential Backoff
ตัวอย่างเช่น ลองพิจารณาแอปพลิเคชันที่ต้องการส่งคำขอต่อไปนี้ไปยัง Time Zone API
https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510×tamp=1331161200&key=YOUR_API_KEYตัวอย่าง Python ต่อไปนี้แสดงวิธีส่งคำขอด้วยการหยุดชั่วคราวแบบทวีคูณ
import json import time import urllib.error import urllib.parse import urllib.request # The maps_key defined below isn't a valid Google Maps API key. # You need to get your own API key. # See https://developers.google.com/maps/documentation/timezone/get-api-key API_KEY = "YOUR_KEY_HERE" TIMEZONE_BASE_URL = "https://maps.googleapis.com/maps/api/timezone/json" def timezone(lat, lng, timestamp): # Join the parts of the URL together into one string. params = urllib.parse.urlencode( {"location": f"{lat},{lng}", "timestamp": timestamp, "key": API_KEY,} ) url = f"{TIMEZONE_BASE_URL}?{params}" current_delay = 0.1 # Set the initial retry delay to 100ms. max_delay = 5 # Set the maximum retry delay to 5 seconds. while True: try: # Get the API response. response = urllib.request.urlopen(url) except urllib.error.URLError: pass # Fall through to the retry loop. else: # If we didn't get an IOError then parse the result. result = json.load(response) if result["status"] == "OK": return result["timeZoneId"] elif result["status"] != "UNKNOWN_ERROR": # Many API errors cannot be fixed by a retry, e.g. INVALID_REQUEST or # ZERO_RESULTS. There is no point retrying these requests. raise Exception(result["error_message"]) if current_delay > max_delay: raise Exception("Too many retry attempts.") print("Waiting", current_delay, "seconds before retrying.") time.sleep(current_delay) current_delay *= 2 # Increase the delay each time we retry. if __name__ == "__main__": tz = timezone(39.6034810, -119.6822510, 1331161200) print(f"Timezone: {tz}")
นอกจากนี้ คุณควรระมัดระวังไม่ให้มีโค้ดลองอีกครั้งที่สูงกว่าในห่วงโซ่การเรียกแอปพลิเคชัน ซึ่งนำไปสู่คำขอที่ซ้ำกันอย่างรวดเร็ว
คำขอที่ซิงค์
คำขอจำนวนมากที่ซิงค์กับ API ของ Google อาจดูเหมือนการโจมตีแบบปฏิเสธการให้บริการแบบกระจาย (DDoS) ในโครงสร้างพื้นฐานของ Google และจะได้รับการจัดการตามนั้น หากต้องการหลีกเลี่ยงปัญหานี้ คุณควรตรวจสอบว่าคำขอ API ไม่ได้ซิงค์ข้อมูลระหว่างไคลเอ็นต์
เช่น ลองพิจารณาแอปพลิเคชันที่แสดงเวลาในเขตเวลาปัจจุบัน แอปพลิเคชันนี้อาจตั้งปลุกในระบบปฏิบัติการของไคลเอ็นต์เพื่อปลุกระบบเมื่อเริ่มนาทีเพื่อให้สามารถอัปเดตเวลาที่แสดงได้ แอปพลิเคชันไม่ควรเรียก API ใดๆ เป็นส่วนหนึ่งของการประมวลผลที่เชื่อมโยงกับการเตือนนั้น
การเรียกใช้ API เพื่อตอบสนองต่อการปลุกที่ตั้งเวลาไว้ไม่ดี เนื่องจากจะทำให้การเรียกใช้ API ซิงค์กับการเริ่มต้นของนาที แม้ว่าจะเป็นระหว่างอุปกรณ์ต่างๆ แทนที่จะกระจายอย่างสม่ำเสมอตลอดเวลา แอปพลิเคชันที่ออกแบบมาไม่ดีซึ่งทำเช่นนี้จะทำให้เกิดการเพิ่มขึ้นของ การเข้าชมที่ระดับปกติ 60 เท่าเมื่อเริ่มต้นในแต่ละนาที
แต่การออกแบบที่ดีอย่างหนึ่งที่เป็นไปได้คือการตั้งปลุกที่ 2 ในเวลาที่สุ่มเลือก เมื่อนาฬิกาปลุกที่ 2 ดังขึ้น แอปพลิเคชันจะเรียกใช้ API ที่ต้องการและจัดเก็บผลลัพธ์ เมื่อแอปพลิเคชันต้องการอัปเดตการแสดงผลเมื่อเริ่มต้นนาที แอปพลิเคชันจะใช้ ผลลัพธ์ที่จัดเก็บไว้ก่อนหน้านี้แทนการเรียก API อีกครั้ง เมื่อใช้วิธีนี้ การเรียก API จะกระจายอย่างสม่ำเสมอตลอดระยะเวลา นอกจากนี้ การเรียก API จะไม่ทำให้การแสดงผลล่าช้าเมื่อมีการอัปเดตจอแสดงผล
นอกเหนือจากช่วงต้นนาทีแล้ว เวลาการซิงค์อื่นๆ ที่พบบ่อยซึ่งคุณควรไม่กำหนดเป้าหมายคือช่วงต้นชั่วโมงและช่วงต้นของแต่ละวันที่เที่ยงคืน
การประมวลผลคำตอบ
ส่วนนี้จะอธิบายวิธีดึงค่าเหล่านี้แบบไดนามิกจากการตอบกลับของเว็บเซอร์วิส
บริการเว็บของ Google Maps ให้การตอบกลับที่เข้าใจง่าย แต่ไม่ค่อยเป็นมิตรกับผู้ใช้ เมื่อทำการค้นหา คุณอาจต้องการดึงค่าที่เฉพาะเจาะจงเพียงไม่กี่ค่าแทนที่จะแสดงชุดข้อมูล โดยทั่วไป คุณจะต้องแยกวิเคราะห์การตอบกลับจากเว็บ เซอร์วิสและดึงเฉพาะค่าที่คุณสนใจ
รูปแบบการแยกวิเคราะห์ที่คุณใช้จะขึ้นอยู่กับว่าคุณจะแสดงผลลัพธ์ในรูปแบบ XML หรือ JSON การตอบกลับ JSON ซึ่งอยู่ในรูปแบบของออบเจ็กต์ Javascript อยู่แล้ว อาจได้รับการประมวลผลภายใน Javascript เอง ในไคลเอ็นต์ ควรประมวลผลการตอบสนองด้วย XML โดยใช้โปรแกรมประมวลผล XML และภาษาการค้นหา XML เพื่อจัดการองค์ประกอบภายในรูปแบบ XML เราใช้ XPath ในตัวอย่างต่อไปนี้ เนื่องจากโดยทั่วไปแล้วไลบรารีการประมวลผล XML จะรองรับ XPath
การประมวลผล XML ด้วย XPath
XML เป็นรูปแบบข้อมูลที่มีโครงสร้างที่ค่อนข้างสมบูรณ์ซึ่งใช้สำหรับการแลกเปลี่ยนข้อมูล แม้ว่า XML จะไม่ได้มีน้ำหนักเบาเท่า JSON แต่ก็รองรับภาษาและมีเครื่องมือที่แข็งแกร่งกว่า โค้ดสำหรับ
การประมวลผล XML ใน Java เช่น สร้างขึ้นในแพ็กเกจ javax.xml
เมื่อประมวลผลการตอบสนองด้วย XML คุณควรใช้ภาษาการค้นหาที่เหมาะสมเพื่อเลือกโหนดภายในเอกสาร XML แทนที่จะถือว่าองค์ประกอบอยู่ในตำแหน่งสัมบูรณ์ภายในมาร์กอัป XML XPath เป็นไวยากรณ์ของภาษาที่ใช้อธิบายโหนดและองค์ประกอบ ภายในเอกสาร XML โดยไม่ซ้ำกัน นิพจน์ XPath ช่วยให้คุณระบุ เนื้อหาที่เฉพาะเจาะจงภายในเอกสารการตอบกลับ XML ได้
นิพจน์ XPath
ความคุ้นเคยกับ XPath จะช่วยให้คุณพัฒนา รูปแบบการแยกวิเคราะห์ที่แข็งแกร่งได้ ส่วนนี้จะมุ่งเน้นที่วิธีระบุองค์ประกอบ ภายในเอกสาร XML ด้วย XPath ซึ่งจะช่วยให้คุณ ระบุองค์ประกอบหลายรายการและสร้างการค้นหาที่ซับซ้อนได้
XPath ใช้นิพจน์เพื่อเลือกองค์ประกอบภายในเอกสาร XML โดยใช้ไวยากรณ์ที่คล้ายกับที่ใช้สำหรับเส้นทางไดเรกทอรี นิพจน์เหล่านี้จะระบุองค์ประกอบภายในแผนผังเอกสาร XML ซึ่งเป็นแผนผังแบบลำดับชั้นที่คล้ายกับ DOM โดยทั่วไป นิพจน์ XPath จะทำงานอย่างกว้างขวาง ซึ่งหมายความว่านิพจน์จะจับคู่โหนดทั้งหมดที่ตรงกับเกณฑ์ที่ระบุ
เราจะใช้ XML แบบย่อต่อไปนี้เพื่อแสดงตัวอย่าง
<WebServiceResponse> <status>OK</status> <result> <type>sample</type> <name>Sample XML</name> <location> <lat>37.4217550</lat> <lng>-122.0846330</lng> </location> </result> <result> <message>The secret message</message> </result> </WebServiceResponse>
การเลือกโหนดในนิพจน์
การเลือก XPath จะเลือกโหนด โหนดรูท
ครอบคลุมทั้งเอกสาร คุณเลือกโหนดนี้ได้โดยใช้
นิพจน์พิเศษ "/" โปรดทราบว่าโหนดรูท
ไม่ใช่โหนดระดับบนสุดของเอกสาร XML แต่จะ
อยู่เหนือองค์ประกอบระดับบนสุดนี้ 1 ระดับและรวม
องค์ประกอบดังกล่าวไว้ด้วย
โหนดองค์ประกอบแสดงองค์ประกอบต่างๆ ภายในแผนผังเอกสาร XML
องค์ประกอบ <WebServiceResponse> เช่น แสดงถึงองค์ประกอบระดับบนสุดที่แสดงผลใน
บริการตัวอย่างด้านบน คุณเลือกโหนดแต่ละรายการได้ผ่านเส้นทางแบบสัมบูรณ์หรือแบบสัมพัทธ์ ซึ่งระบุโดยมีหรือไม่มีอักขระ "/" นำหน้า
- เส้นทางแบบสัมบูรณ์: นิพจน์ "
/WebServiceResponse/result" จะเลือกโหนด<result>ทั้งหมดที่ เป็นโหนดย่อยของโหนด<WebServiceResponse>(โปรดทราบว่าทั้ง 2 องค์ประกอบนี้สืบทอดมาจากโหนดรูท "/") - เส้นทางแบบสัมพัทธ์จากบริบทปัจจุบัน: นิพจน์
"
result" จะตรงกับองค์ประกอบ<result>ใดๆ ภายในบริบทปัจจุบัน โดยทั่วไปแล้ว คุณไม่ควรต้องกังวลเกี่ยวกับบริบท เนื่องจากโดยปกติคุณจะประมวลผลผลลัพธ์ของบริการเว็บผ่านนิพจน์เดียว
คุณอาจเพิ่มนิพจน์เหล่านี้ได้โดยการเพิ่มเส้นทางไวลด์การ์ดซึ่งระบุด้วยเครื่องหมายทับคู่ ("//")
ไวลด์การ์ดนี้ระบุว่าอาจมีองค์ประกอบ 0 รายการขึ้นไปที่ตรงกันในเส้นทางที่แทรก เช่น นิพจน์ XPath "//formatted_address"
จะตรงกับโหนดทั้งหมดที่มีชื่อนั้นในเอกสารปัจจุบัน
นิพจน์ //viewport//lat จะตรงกับองค์ประกอบ <lat> ทั้งหมดที่สามารถติดตาม <viewport>
เป็นองค์ประกอบหลัก
โดยค่าเริ่มต้น นิพจน์ XPath จะตรงกับองค์ประกอบทั้งหมด คุณสามารถจำกัดนิพจน์ให้ตรงกับองค์ประกอบหนึ่งๆ ได้โดยระบุเพรดิเคต
ซึ่งอยู่ในวงเล็บเหลี่ยม ([]) เช่น นิพจน์ XPath "/GeocodeResponse/result[2] จะแสดงผลลัพธ์ที่ 2 เสมอ
| ประเภทของนิพจน์ | |
|---|---|
| โหนดราก | นิพจน์ XPath: "
/"การเลือก:
<WebServiceResponse>
<status>OK</status>
<result>
<type>sample</type>
<name>Sample XML</name>
<location>
<lat>37.4217550</lat>
<lng>-122.0846330</lng>
</location>
</result>
<result>
<message>The secret message</message>
</result>
</WebServiceResponse>
|
| เส้นทางแบบเต็ม | นิพจน์ XPath: "
/WebServiceResponse/result"การเลือก:
<result>
<type>sample</type>
<name>Sample XML</name>
<location>
<lat>37.4217550</lat>
<lng>-122.0846330</lng>
</location>
</result>
<result>
<message>The secret message</message>
</result>
|
| เส้นทางที่มีไวลด์การ์ด | นิพจน์ XPath: "
/WebServiceResponse//location"การเลือก:
<location>
<lat>37.4217550</lat>
<lng>-122.0846330</lng>
</location>
|
| เส้นทางที่มี Predicate | นิพจน์ XPath: "
/WebServiceResponse/result[2]/message"การเลือก:
<message>The secret message</message>
|
รายการย่อยโดยตรงทั้งหมดของ result แรก |
นิพจน์ XPath: "
/WebServiceResponse/result[1]/*"การเลือก:
<type>sample</type>
<name>Sample XML</name>
<location>
<lat>37.4217550</lat>
<lng>-122.0846330</lng>
</location>
|
name ของ
result ที่มีข้อความ type เป็น "ตัวอย่าง" |
นิพจน์ XPath: "
/WebServiceResponse/result[type/text()='sample']/name"การเลือก:
Sample XML
|
โปรดทราบว่าเมื่อเลือกองค์ประกอบ คุณจะเลือกโหนด ไม่ใช่แค่ข้อความภายในออบเจ็กต์เหล่านั้น โดยทั่วไป คุณ จะต้องวนซ้ำโหนดที่ตรงกันทั้งหมดและดึงข้อความออกมา คุณยังจับคู่โหนดข้อความโดยตรงได้ด้วย ดูโหนดข้อความ ด้านล่าง
โปรดทราบว่า XPath รองรับโหนดแอตทริบิวต์ด้วย แต่ บริการเว็บของ Google Maps ทั้งหมดจะแสดงองค์ประกอบที่ไม่มีแอตทริบิวต์ ดังนั้น จึงไม่จำเป็นต้องจับคู่แอตทริบิวต์
การเลือกข้อความในนิพจน์
ข้อความภายในเอกสาร XML จะระบุไว้ในนิพจน์ XPath
ผ่านตัวดำเนินการโหนดข้อความ โอเปอเรเตอร์ "text()"
ระบุการแยกข้อความจากโหนดที่ระบุ ตัวอย่างเช่น
นิพจน์ XPath "//formatted_address/text()" จะ
แสดงข้อความทั้งหมดภายในองค์ประกอบ <formatted_address>
| ประเภทของนิพจน์ | |
|---|---|
| โหนดข้อความทั้งหมด (รวมถึงช่องว่าง) | นิพจน์ XPath: "
//text()"การเลือก:
sample
Sample XML
37.4217550
-122.0846330
The secret message
|
| การเลือกข้อความ | นิพจน์ XPath: "
/WebServiceRequest/result[2]/message/text()"การเลือก:
The secret message
|
| การเลือกตามบริบท | นิพจน์ XPath: "
/WebServiceRequest/result[type/text() = 'sample']/name/text()"การเลือก:
Sample XML
|
หรือคุณจะประเมินนิพจน์และแสดงผลชุด ของโหนด แล้ววนซ้ำ "ชุดโหนด" นั้นเพื่อดึงข้อความจากแต่ละโหนดก็ได้ เราใช้วิธีนี้ในตัวอย่างด้านล่าง
ดูข้อมูลเพิ่มเติมเกี่ยวกับ XPath ได้ที่ข้อกำหนดเฉพาะ XPath ของ W3C
การประเมิน XPath ใน Java
Java รองรับการแยกวิเคราะห์ XML และการใช้นิพจน์ XPath
ภายในแพ็กเกจ javax.xml.xpath.* อย่างกว้างขวาง
ด้วยเหตุนี้ โค้ดตัวอย่างในส่วนนี้จึงใช้ Java เพื่อ
แสดงวิธีจัดการ XML และแยกวิเคราะห์ข้อมูลจากการตอบกลับของบริการ XML
หากต้องการใช้ XPath ในโค้ด Java ก่อนอื่นคุณจะต้องสร้างอินสแตนซ์ของ XPathFactory และเรียกใช้ newXPath() ใน Factory นั้นเพื่อสร้างออบเจ็กต์ XPath
จากนั้นออบเจ็กต์นี้จะประมวลผล XML
และนิพจน์ XPath ที่ส่งผ่านโดยใช้เมธอด evaluate()
เมื่อประเมินนิพจน์ XPath ให้ตรวจสอบว่าคุณได้ทำซ้ำ
ใน "ชุดโหนด" ที่เป็นไปได้ทั้งหมดซึ่งอาจมีการส่งคืน เนื่องจากระบบจะแสดงผลลัพธ์เหล่านี้เป็นโหนด DOM ในโค้ด Java คุณจึงควรบันทึกค่าหลายค่าดังกล่าวภายในออบเจ็กต์ NodeList และวนซ้ำออบเจ็กต์นั้นเพื่อดึงข้อความหรือค่าจากโหนดเหล่านั้น
โค้ดต่อไปนี้แสดงวิธีสร้างออบเจ็กต์ XPath
กำหนด XML และนิพจน์ XPath ให้กับออบเจ็กต์ และประเมินนิพจน์เพื่อพิมพ์เนื้อหาที่เกี่ยวข้อง
import org.xml.sax.InputSource; import org.w3c.dom.*; import javax.xml.xpath.*; import java.io.*; public class SimpleParser { public static void main(String[] args) throws IOException { XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); try { System.out.print("Web Service Parser 1.0\n"); // In practice, you'd retrieve your XML via an HTTP request. // Here we simply access an existing file. File xmlFile = new File("XML_FILE"); // The xpath evaluator requires the XML be in the format of an InputSource InputSource inputXml = new InputSource(new FileInputStream(xmlFile)); // Because the evaluator may return multiple entries, we specify that the expression // return a NODESET and place the result in a NodeList. NodeList nodes = (NodeList) xpath.evaluate("XPATH_EXPRESSION", inputXml, XPathConstants.NODESET); // We can then iterate over the NodeList and extract the content via getTextContent(). // NOTE: this will only return text for element nodes at the returned context. for (int i = 0, n = nodes.getLength(); i < n; i++) { String nodeString = nodes.item(i).getTextContent(); System.out.print(nodeString); System.out.print("\n"); } } catch (XPathExpressionException ex) { System.out.print("XPath Error"); } catch (FileNotFoundException ex) { System.out.print("File Error"); } } }