เว็บเซอร์วิสของ Google Maps Platform คือชุดอินเทอร์เฟซ HTTP สำหรับบริการของ Google ที่ให้ข้อมูลทางภูมิศาสตร์สำหรับแอปพลิเคชันแผนที่ของคุณ
คู่มือนี้อธิบายแนวทางปฏิบัติทั่วไปบางอย่างที่เป็นประโยชน์สำหรับการตั้งค่าคำขอเว็บเซอร์วิสและการประมวลผลการตอบกลับของบริการ ดูเอกสารประกอบฉบับเต็มของ Geocoding API ได้ในคู่มือสำหรับนักพัฒนาซอฟต์แวร์
บริการบนเว็บคืออะไร
เว็บเซอร์วิสของ Google Maps Platform เป็นอินเทอร์เฟซสำหรับขอข้อมูล Maps API จากบริการภายนอกและใช้ข้อมูลภายในแอปพลิเคชัน Maps บริการเหล่านี้ออกแบบมาเพื่อใช้ร่วมกับแผนที่ตามข้อจำกัดของใบอนุญาตในข้อกำหนดในการให้บริการของ Google Maps Platform
เว็บเซอร์วิสของ Maps API ใช้คำขอ HTTP(S) ไปยัง URL ที่เฉพาะเจาะจง โดยส่งพารามิเตอร์ของ URL และ/หรือข้อมูล POST ในรูปแบบ JSON เป็นอาร์กิวเมนต์ไปยังบริการ โดยทั่วไป บริการเหล่านี้จะแสดงผลข้อมูลในเนื้อหาการตอบกลับเป็น JSON หรือ XML เพื่อให้แอปพลิเคชันแยกวิเคราะห์และ/หรือประมวลผล
คำขอ Geocoding API ทั่วไปมักจะอยู่ในรูปแบบต่อไปนี้
https://maps.googleapis.com/maps/api/geocode/output?parameters
โดย output จะระบุรูปแบบการตอบกลับ (โดยปกติคือ json หรือ xml)
หมายเหตุ: แอปพลิเคชัน Geocoding API ทั้งหมดต้องมีการตรวจสอบสิทธิ์ ดูข้อมูลเพิ่มเติมเกี่ยวกับข้อมูลรับรองการตรวจสอบสิทธิ์
การเข้าถึง SSL/TLS
คำขอ Google Maps Platform ทั้งหมดที่ใช้คีย์ API หรือมีข้อมูลผู้ใช้ต้องใช้ HTTPS ระบบอาจปฏิเสธคำขอที่ส่งผ่าน HTTP ซึ่งมีข้อมูลที่ละเอียดอ่อน
การสร้าง URL ที่ถูกต้อง
คุณอาจคิดว่า URL ที่ "ถูกต้อง" นั้นชัดเจนในตัวเอง แต่จริงๆ แล้วไม่ใช่เช่นนั้น ตัวอย่างเช่น URL ที่ป้อนในแถบที่อยู่ของเบราว์เซอร์อาจมีสัญลักษณ์พิเศษ (เช่น "上海+中國") ซึ่งเบราว์เซอร์ต้องแปลสัญลักษณ์เหล่านั้นเป็นการเข้ารหัสอื่นภายในก่อนที่จะส่ง
ในทำนองเดียวกัน โค้ดใดๆ ที่สร้างหรือยอมรับอินพุต UTF-8 อาจถือว่า URL ที่มีอักขระ UTF-8 เป็น "ถูกต้อง" แต่ก็ต้องแปลอักขระเหล่านั้นก่อนที่จะส่งไปยังเว็บเซิร์ฟเวอร์ด้วย
กระบวนการนี้เรียกว่า
การเข้ารหัส URL หรือการเข้ารหัสเปอร์เซ็นต์
อักขระพิเศษ
เราจำเป็นต้องแปลสัญลักษณ์พิเศษเนื่องจาก URL ทั้งหมดต้องเป็นไปตามไวยากรณ์ที่ระบุไว้ในข้อกำหนดตัวระบุทรัพยากรสากล (URI) ซึ่งหมายความว่า URL ต้องมีเฉพาะชุดย่อยพิเศษของอักขระ ASCII เท่านั้น ซึ่งก็คือสัญลักษณ์ที่เป็นตัวอักษรและตัวเลขคละกันที่คุ้นเคย และอักขระที่สงวนไว้บางตัวเพื่อใช้เป็นอักขระควบคุมภายใน URL ตารางนี้สรุปอักขระเหล่านี้ไว้ดังนี้
| ตั้งค่า | อักขระ | การใช้ URL |
|---|---|---|
| ตัวอักษรและตัวเลขคละกัน | a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 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 โดยถือว่าข้อมูลที่ผู้ใช้ป้อนเป็นอักขระตามตัวอักษร
นอกจากนี้ URL ยังมีความยาวไม่เกิน 16384 อักขระสำหรับเว็บเซอร์วิสและ Web API แบบคงที่ทั้งหมดของ Google Maps Platform สำหรับบริการส่วนใหญ่ จำนวนอักขระสูงสุดนี้จะไม่ค่อยมีผล อย่างไรก็ตาม โปรดทราบว่าบริการบางอย่างมีพารามิเตอร์หลายรายการที่อาจส่งผลให้ URL ยาว
การใช้ Google APIs อย่างเหมาะสม
ไคลเอ็นต์ API ที่ออกแบบมาไม่ดีอาจทำให้ทั้งอินเทอร์เน็ตและเซิร์ฟเวอร์ของ Google มีภาระงานมากเกินความจำเป็น ส่วนนี้ประกอบด้วยแนวทางปฏิบัติแนะนำบางส่วนสำหรับไคลเอ็นต์ของ API การปฏิบัติตามแนวทางแนะนำเหล่านี้จะช่วยป้องกันไม่ให้แอปพลิเคชันของคุณถูกบล็อกเนื่องจากการละเมิด API โดยไม่ตั้งใจ
การจัดการข้อผิดพลาดและการลองอีกครั้ง
ดูข้อมูลเกี่ยวกับโค้ดตอบกลับ UNKNOWN_ERROR หรือ OVER_QUERY_LIMIT จาก Geocoding 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 ต่อไปนี้แสดงวิธีส่งคำขอด้วย Exponential Backoff
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 อาจดูเหมือนการโจมตีแบบ Distributed Denial of Service (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 รองรับโดยทั่วไป
การประมวลผล 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> แสดงถึงองค์ประกอบระดับบนสุดที่แสดงผลในบริการตัวอย่างด้านบน คุณเลือกโหนดแต่ละโหนดผ่าน Absolute Path หรือ Relative Path ซึ่งระบุโดยการมีหรือไม่มีอักขระ "/" นำหน้า
- Absolute Path: นิพจน์ "
/WebServiceResponse/result" จะเลือกโหนด<result>ทั้งหมดที่เป็นโหนดย่อยของโหนด<WebServiceResponse>(โปรดทราบว่าองค์ประกอบทั้ง 2 รายการนี้สืบทอดมาจากโหนดรูท "/") - Relative Path จากบริบทปัจจุบัน: นิพจน์ "
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>
|
| Absolute Path | นิพจน์ 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>
|
| เส้นทางที่มีเพรดิเคต | นิพจน์ 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 เป็น "sample" |
นิพจน์ 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() ในโรงงานนั้นเพื่อสร้างออบเจ็กต์ 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"); } } }