แนวทางปฏิบัติแนะนำสำหรับการใช้บริการบนเว็บของ Elevation API

บริการบนเว็บของ Google Maps Platform คือชุดของอินเทอร์เฟซ HTTP สำหรับบริการของ Google ที่ให้ข้อมูลทางภูมิศาสตร์สำหรับแอปพลิเคชันแผนที่

คู่มือนี้จะอธิบายแนวทางปฏิบัติทั่วไปบางส่วนซึ่งเป็นประโยชน์ในการตั้งค่า คำขอบริการเว็บ และการประมวลผลการตอบสนองของบริการ ดูคู่มือสำหรับนักพัฒนาซอฟต์แวร์เพื่อดูเอกสารฉบับเต็มของ Elevation API

บริการผ่านเว็บคืออะไร

บริการบนเว็บของ Google Maps Platform เป็นอินเทอร์เฟซสำหรับขอข้อมูล Maps API จากบริการภายนอกและใช้ข้อมูลภายในแอปพลิเคชัน Maps บริการเหล่านี้ออกแบบมาให้ใช้ร่วมกับแผนที่ตามข้อจำกัดของใบอนุญาตในข้อกำหนดในการให้บริการของ Google Maps Platform

บริการบนเว็บของ Maps API ใช้คำขอ HTTP(S) ไปยัง URL ที่เจาะจงโดยการส่งพารามิเตอร์ของ URL และ/หรือข้อมูล POST ในรูปแบบ JSON เป็นอาร์กิวเมนต์ไปยังบริการ โดยทั่วไป บริการเหล่านี้จะแสดงผลข้อมูลในเนื้อหาการตอบสนองเป็น JSON หรือ XML สำหรับการแยกวิเคราะห์และ/หรือประมวลผลโดยแอปพลิเคชันของคุณ

คำขอ Elevation API โดยทั่วไปจะมีรูปแบบดังนี้

https://maps.googleapis.com/maps/api/elevation/output?parameters

โดยที่ output บ่งบอกถึงรูปแบบคำตอบ (โดยปกติคือ json หรือ xml)

หมายเหตุ: แอปพลิเคชัน Elevation API ทั้งหมดต้องมีการตรวจสอบสิทธิ์ ดูข้อมูลเพิ่มเติมเกี่ยวกับข้อมูลเข้าสู่ระบบสำหรับการตรวจสอบสิทธิ์

การเข้าถึง SSL/TLS

ต้องมี HTTPS สำหรับคำขอ Google Maps Platform ทั้งหมดที่ใช้คีย์ API หรือมีข้อมูลผู้ใช้ ระบบอาจปฏิเสธคำขอผ่าน HTTP ซึ่งมีข้อมูลที่ละเอียดอ่อน

การสร้าง URL ที่ถูกต้อง

คุณอาจคิดว่า URL ที่ "ถูกต้อง" นั้นชัดเจนในตัวเอง แต่ก็ไม่เป็นเช่นนั้น เช่น URL ที่ป้อนลงในแถบที่อยู่ในเบราว์เซอร์อาจมีสัญลักษณ์พิเศษ (เช่น "上海+中國") เบราว์เซอร์ต้องแปลอักขระเหล่านั้นเป็นการเข้ารหัสภายในก่อนที่จะส่ง เช่นเดียวกับโทเค็นเดียวกัน โค้ดที่สร้างหรือยอมรับอินพุต UTF-8 อาจปฏิบัติกับ URL ที่มีอักขระ UTF-8 ว่า "ถูกต้อง" แต่ก็ต้องแปลอักขระเหล่านั้นก่อนที่จะส่งไปยังเว็บเซิร์ฟเวอร์ด้วย กระบวนการนี้เรียกว่า การเข้ารหัส URL หรือการเข้ารหัสด้วยเปอร์เซ็นต์

สัญลักษณ์พิเศษ

เราต้องแปลสัญลักษณ์พิเศษเนื่องจาก URL ทั้งหมดต้องสอดคล้องกับไวยากรณ์ที่ระบุโดยข้อกำหนด Uniform Resource Identifier (URI) ซึ่งหมายความว่า URL ต้องมีเฉพาะชุดย่อยพิเศษของอักขระ ASCII ได้แก่ สัญลักษณ์ที่เป็นตัวอักษรและตัวเลขคละกันที่คุ้นเคย และอักขระที่สงวนไว้บางตัวเพื่อใช้เป็นอักขระควบคุมภายใน URL ตารางนี้จะสรุปอักขระเหล่านี้

สรุปอักขระของ 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 X Y Z 0 1 2 3 4 สตริงข้อความ การใช้รูปแบบ (http) พอร์ต (8080) ฯลฯ
ไม่ได้จอง - _ ~ สตริงข้อความ
จองแล้ว ! * ' ( ) ; : @ & = + $ , / ? % # [ ] อักขระควบคุมและ/หรือสตริงข้อความ

เมื่อสร้าง URL ที่ถูกต้อง คุณต้องตรวจสอบว่า URL มีเฉพาะอักขระที่แสดงในตารางสรุปอักขระของ URL ที่ถูกต้อง การจัดรูปแบบ URL เพื่อใช้อักขระชุดนี้โดยทั่วไปจะนำไปสู่ปัญหา 2 ประการ คือ การละเลยและการแทนที่ 1 อย่าง ได้แก่

  • อักขระที่คุณต้องการจัดการอยู่นอกชุดข้างต้น ตัวอย่างเช่น อักขระในภาษาต่างประเทศอย่าง 上海+中國 ต้องเข้ารหัสโดยใช้อักขระข้างต้น ตามรูปแบบยอดนิยม ช่องว่าง (ซึ่งไม่อนุญาตให้ใช้ใน URL) มักจะแสดงโดยใช้อักขระบวก '+' ด้วยเช่นกัน
  • อักขระจะอยู่ในชุดด้านบนเป็นอักขระที่สงวนไว้ แต่ต้องใช้ตามตัวอักษร ตัวอย่างเช่น ? ใช้ภายใน URL เพื่อระบุจุดเริ่มต้นของสตริงการค้นหา หากต้องการใช้สตริง "? และ 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

อักขระทั่วไปที่ต้องเข้ารหัส

อักขระทั่วไปบางตัวที่ต้องเข้ารหัส ได้แก่

อักขระที่ไม่ปลอดภัย ค่าที่เข้ารหัส
เว้นวรรค %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

บางครั้งการแปลง URL ที่คุณได้รับจากอินพุตของผู้ใช้อาจยุ่งยาก ตัวอย่างเช่น ผู้ใช้อาจป้อนที่อยู่เป็น "5th&Main St." โดยทั่วไปคุณควรสร้าง URL จากส่วนต่างๆ ของ URL โดยถือว่าข้อมูลที่ผู้ใช้ป้อนเป็นอักขระตามตัวอักษร

นอกจากนี้ URL ยังมีอักขระได้ไม่เกิน 16, 384 ตัวสำหรับบริการเว็บ Google Maps Platform และ API เว็บแบบคงที่ทั้งหมด สำหรับบริการส่วนใหญ่ จำนวนอักขระสูงสุดนี้จะไม่ค่อยถึงขีดจำกัดนี้ อย่างไรก็ตาม โปรดทราบว่าบริการบางอย่างมีพารามิเตอร์หลายรายการที่อาจส่งผลให้ URL มีความยาวได้

การใช้ Google API อย่างสุภาพ

ไคลเอ็นต์ 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&timestamp=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 อาจดูเหมือนการโจมตีแบบ Distributiond Denial of Service (DDoS) บนโครงสร้างพื้นฐานของ Google และได้รับการจัดการตามนั้น หากไม่ต้องการให้เป็นเช่นนั้น คุณควรตรวจสอบว่าคำขอ API ไม่ได้ซิงค์ข้อมูลระหว่างไคลเอ็นต์

ตัวอย่างเช่น ลองพิจารณาแอปพลิเคชันที่แสดงเวลาในเขตเวลาปัจจุบัน แอปพลิเคชันนี้อาจตั้งปลุกในระบบปฏิบัติการของไคลเอ็นต์ให้ปลุกระบบเมื่อเริ่มต้นนาทีเพื่อให้สามารถอัปเดตเวลาที่แสดงได้ แอปพลิเคชันไม่ควรเรียก API เป็นส่วนหนึ่งของการประมวลผลที่เกี่ยวข้องกับการปลุกนั้น

การเรียก API เพื่อตอบสนองต่อการแจ้งเตือนแบบคงที่นั้นไม่ดี เนื่องจากทำให้การเรียก API ซิงค์กับจุดเริ่มต้นของนาทีแม้ระหว่างอุปกรณ์ต่างๆ มากกว่าจะเป็นการกระจายอย่างสม่ำเสมอเมื่อเวลาผ่านไป แอปพลิเคชันที่ออกแบบมาไม่ดีซึ่งจะทำให้การเข้าชมเพิ่มขึ้นอย่างรวดเร็วที่ระดับปกติถึง 60 เท่าในช่วงเริ่มต้นแต่ละนาที

แต่วิธีที่ดีอย่างหนึ่งที่เป็นไปได้คือการปลุกครั้งที่ 2 ให้เป็นเวลาที่เลือกมาแบบสุ่ม เมื่อการปลุกครั้งที่ 2 นี้เริ่มการทำงานของแอปพลิเคชันจะเรียก API ที่ต้องใช้และจัดเก็บผลลัพธ์ไว้ เมื่อแอปพลิเคชันต้องการอัปเดตการแสดงผลเมื่อเริ่มต้นนาที แอปพลิเคชันจะใช้ผลลัพธ์ที่จัดเก็บไว้ก่อนหน้านี้แทนการเรียกใช้ API อีกครั้ง วิธีนี้ทำให้การเรียก API จะกระจายอย่างเท่าๆ กันเมื่อเวลาผ่านไป นอกจากนี้ การเรียก API จะไม่ทำให้การแสดงผลล่าช้าเมื่อมีการอัปเดตจอแสดงผล

นอกเหนือจากจุดเริ่มต้นของนาทีแล้ว เวลาซิงค์ข้อมูลทั่วไปอื่นๆ ที่คุณไม่ควรกำหนดเป้าหมายคือจุดเริ่มต้นของชั่วโมงและเวลาเริ่มต้นของแต่ละวันคือตอนเที่ยงคืน

กำลังประมวลผลคำตอบ

ส่วนนี้จะพูดถึงวิธีแยกค่าเหล่านี้แบบไดนามิกจากการตอบกลับของบริการเว็บ

บริการผ่านเว็บของ Google Maps ให้คำตอบที่เข้าใจง่าย แต่ไม่เป็นมิตรกับผู้ใช้เสียทีเดียว เมื่อดำเนินการค้นหา แทนที่จะแสดงชุดข้อมูล คุณอาจต้องการดึงค่าเฉพาะขึ้นมา 2-3 ค่า โดยทั่วไป คุณจะต้องแยกวิเคราะห์การตอบกลับจาก บริการเว็บและแยกเฉพาะค่าที่คุณสนใจเท่านั้น

รูปแบบการแยกวิเคราะห์ที่คุณใช้ขึ้นอยู่กับว่าคุณส่งคืนเอาต์พุตเป็น XML หรือ JSON การตอบสนอง JSON ซึ่งอยู่ในรูปแบบออบเจ็กต์ JavaScript อยู่แล้วอาจประมวลผลภายใน JavaScript บนไคลเอ็นต์ได้ การตอบกลับ XML ควรได้รับการประมวลผลโดยใช้ตัวประมวลผล XML และภาษาของการค้นหา XML เพื่อระบุองค์ประกอบภายในรูปแบบ XML เราใช้ XPath ในตัวอย่างต่อไปนี้ เนื่องจากระบบรองรับโดยทั่วไปในไลบรารีการประมวลผล XML

การประมวลผล XML ด้วย XPath

XML เป็นรูปแบบข้อมูลที่มีโครงสร้างที่สมบูรณ์และใช้ในการแลกเปลี่ยนข้อมูล แม้ว่าจะไม่ได้ใช้งานง่ายเท่ากับ JSON แต่ XML รองรับภาษาได้มากกว่าและเครื่องมือที่มีประสิทธิภาพมากกว่า เช่น โค้ดสำหรับการประมวลผล XML ใน Java จะมีอยู่ในแพ็กเกจ javax.xml

เมื่อประมวลผลการตอบสนองด้วย XML คุณควรใช้ภาษาคำค้นหาที่เหมาะสมในการเลือกโหนดภายในเอกสาร XML แทนการคิดว่าองค์ประกอบอยู่ที่ตำแหน่งสัมบูรณ์ภายในมาร์กอัป XML XPath คือไวยากรณ์ภาษาสำหรับการอธิบายโหนดและองค์ประกอบที่ไม่ซ้ำกันภายในเอกสาร XML นิพจน์ XPath ช่วยให้คุณระบุเนื้อหาที่ต้องการภายในเอกสารการตอบกลับ XML ได้

นิพจน์ XPath

ความคุ้นเคยกับ XPath นั้นดีแต่ช่วยพัฒนารูปแบบการแยกวิเคราะห์ที่มีประสิทธิภาพ ส่วนนี้จะเน้นที่วิธีการที่ XPath ระบุองค์ประกอบในเอกสาร XML ซึ่งจะช่วยให้คุณจัดการองค์ประกอบหลายรายการและสร้างการค้นหาที่ซับซ้อนได้

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> ใดๆ ภายในบริบทปัจจุบัน โดยทั่วไปแล้ว คุณไม่จำเป็นต้องกังวลเกี่ยวกับบริบท เนื่องจากโดยปกติแล้วคุณจะประมวลผลผลลัพธ์บริการเว็บผ่านนิพจน์เดียว

อาจมีการขยายนิพจน์เหล่านี้ 2 นิพจน์ผ่านการเพิ่มเส้นทางไวลด์การ์ด ซึ่งระบุด้วยเครื่องหมายทับคู่ ("//") ไวลด์การ์ดนี้จะระบุว่าองค์ประกอบอย่างน้อย 0 รายการอาจตรงกับเส้นทางการสอดแทรก เช่น นิพจน์ XPath "//formatted_address" จะจับคู่โหนดทั้งหมดของชื่อนั้นในเอกสารปัจจุบัน นิพจน์ //viewport//lat จะตรงกับองค์ประกอบ <lat> ทั้งหมดที่สามารถติดตาม <viewport> ในฐานะพาเรนต์ได้

โดยค่าเริ่มต้น นิพจน์ XPath จะตรงกับองค์ประกอบทั้งหมด คุณจำกัดนิพจน์ให้ตรงกับองค์ประกอบบางรายการได้โดยใส่ predicate ซึ่งอยู่ในวงเล็บเหลี่ยม ([]) นิพจน์ 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>
    
เส้นทางที่มีภาคแสดง
นิพจน์ 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() ในโรงงานนั้นก่อนเพื่อสร้างออบเจ็กต์ 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");
    }
  }
}