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

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

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

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

โดยค่าเริ่มต้น นิพจน์ XPath จะจับคู่องค์ประกอบทั้งหมด คุณจำกัดนิพจน์ให้จับคู่องค์ประกอบบางอย่างได้โดยการใส่predicate ซึ่งอยู่ภายในวงเล็บเหลี่ยม ([]) นิพจน์ XPath "/GeocodeResponse/result[2] จะแสดงผลลัพธ์ที่ 2 เสมอ เป็นต้น

ประเภทนิพจน์
โหนดราก
XPath Expression:  "/"
การเลือก:
    <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 Expression:  "/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 Expression:  "/WebServiceResponse//location"
การเลือก:
    <location>
     <lat>37.4217550</lat>
     <lng>-122.0846330</lng>
    </location>
    
เส้นทางที่มีภาคแสดง
XPath Expression:  "/WebServiceResponse/result[2]/message"
การเลือก:
    <message>The secret message</message>
    
รายการย่อยทั้งหมดของ result แรก
XPath Expression:  "/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 Expression:  "/WebServiceResponse/result[type/text()='sample']/name"
การเลือก:
    Sample XML
    

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

โปรดทราบว่า XPath สนับสนุนโหนดแอตทริบิวต์เช่นกัน แต่บริการบนเว็บทั้งหมดของ Google Maps จะแสดงองค์ประกอบที่ไม่มีแอตทริบิวต์ ดังนั้นการจับคู่แอตทริบิวต์จึงไม่จำเป็น

การเลือกข้อความในนิพจน์

ข้อความภายในเอกสาร XML จะระบุในนิพจน์ XPath ผ่านโอเปอเรเตอร์โหนดข้อความ โอเปอเรเตอร์ "text()" นี้หมายถึงการแยกข้อความจากโหนดที่ระบุ ตัวอย่างเช่น นิพจน์ XPath "//formatted_address/text()" จะแสดงข้อความทั้งหมดภายในองค์ประกอบ <formatted_address>

ประเภทนิพจน์
โหนดข้อความทั้งหมด (รวมช่องว่าง)
XPath Expression:  "//text()"
การเลือก:
    sample
    Sample XML

    37.4217550
    -122.0846330
    The secret message
    
การเลือกข้อความ
XPath Expression:  "/WebServiceRequest/result[2]/message/text()"
การเลือก:
    The secret message
    
การเลือกที่ละเอียดอ่อนตามบริบท
XPath Expression:  "/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");
    }
  }
}