ใช้ XPATH เพื่อค้นหาข้อความที่มี & nbsp;


120

ฉันใช้XPather Browserเพื่อตรวจสอบนิพจน์ XPATH ของฉันบนหน้า HTML

เป้าหมายสุดท้ายของฉันคือใช้นิพจน์เหล่านี้ในซีลีเนียมเพื่อทดสอบอินเทอร์เฟซผู้ใช้ของฉัน

ฉันได้รับไฟล์ HTML ที่มีเนื้อหาคล้ายกับสิ่งนี้:

<tr>
  <td> abc </ td>
  <td> & nbsp; </ td>
</ tr>

ฉันต้องการเลือกโหนดที่มีข้อความที่มีสตริง " &nbsp;"

ด้วยสตริงปกติเช่น "abc" จะไม่มีปัญหา ฉันใช้ XPATH คล้ายกับ//td[text()="abc"].

เมื่อฉันลองใช้ XPATH เหมือน//td[text()="&nbsp;"]มันไม่ส่งคืนอะไรเลย มีกฎพิเศษเกี่ยวกับข้อความที่มี " &" หรือไม่?


การแปลง XSL ที่แท้จริงของคุณไม่คืนค่าอะไรเลยหรือไม่? หรือเฉพาะ Xpather?
Zack The Human

คำตอบ:


89

ดูเหมือนว่าOpenQAซึ่งเป็นผู้ที่อยู่เบื้องหลังซีลีเนียมได้แก้ไขปัญหานี้แล้ว พวกเขากำหนดตัวแปรบางอย่างเพื่อให้ตรงกับช่องว่างอย่างชัดเจน ในกรณีของฉันฉันต้องใช้ XPATH ที่คล้ายกับ//td[text()="${nbsp}"].

ฉันทำซ้ำข้อความจาก OpenQA ที่เกี่ยวข้องกับปัญหานี้ที่นี่ (พบที่นี่ ):

HTML ทำให้ช่องว่างภายในองค์ประกอบเป็นปกติโดยไม่สนใจช่องว่างนำหน้า / ต่อท้ายและแปลงช่องว่างแท็บและบรรทัดใหม่เป็นช่องว่างเดียว เมื่อซีลีเนียมอ่านข้อความนอกหน้ามันจะพยายามทำซ้ำพฤติกรรมนี้ดังนั้นคุณสามารถเพิกเฉยต่อแท็บและบรรทัดใหม่ทั้งหมดใน HTML ของคุณและทำการยืนยันตามลักษณะของข้อความในเบราว์เซอร์เมื่อแสดงผล เราทำสิ่งนี้โดยแทนที่ช่องว่างที่มองไม่เห็นทั้งหมด (รวมถึงช่องว่างที่ไม่ทำลาย " &nbsp;") ด้วยช่องว่างเดียว ทุกบรรทัดใหม่ที่มองเห็น ( <br>, <p>และ<pre>การจัดรูปแบบสายใหม่) ควรจะเก็บรักษาไว้

เราใช้ตรรกะการปรับมาตรฐานเดียวกันกับข้อความของตารางกรณีทดสอบ HTML Selenese สิ่งนี้มีข้อดีหลายประการ ขั้นแรกคุณไม่จำเป็นต้องดูที่ซอร์ส HTML ของหน้าเพื่อดูว่าการยืนยันของคุณควรเป็นอย่างไร " &nbsp;" สัญลักษณ์ที่มองไม่เห็นให้กับผู้ใช้และเพื่อให้คุณไม่ควรจะต้องกังวลเกี่ยวกับพวกเขาเมื่อเขียนทดสอบ Selenese (คุณไม่จำเป็นต้องใส่&nbsp;เครื่องหมาย "" ในกรณีทดสอบของคุณเพื่อ assertText ในฟิลด์ที่มี " &nbsp;") คุณยังสามารถใส่บรรทัดใหม่และช่องว่างเพิ่มเติมใน<td>แท็กSelenese ของคุณ เนื่องจากเราใช้ตรรกะการปรับมาตรฐานเดียวกันกับกรณีทดสอบเช่นเดียวกับที่เราทำกับข้อความเราจึงมั่นใจได้ว่าการยืนยันและข้อความที่แยกออกมาจะตรงกันทุกประการ

สิ่งนี้สร้างปัญหาเล็กน้อยในโอกาสที่หายากเหล่านั้นเมื่อคุณต้องการ / จำเป็นต้องแทรกช่องว่างเพิ่มเติมในกรณีทดสอบของคุณ ตัวอย่างเช่นคุณอาจต้องพิมพ์ข้อความในช่องเช่นนี้: " foo " แต่ถ้าคุณเขียน<td>foo </td>ในกรณีทดสอบ Selenese ของคุณเราจะแทนที่ช่องว่างพิเศษของคุณด้วยช่องว่างเพียงช่องเดียว

ปัญหานี้มีวิธีแก้ปัญหาง่ายๆ เราได้กำหนดตัวแปรใน Selenese ${space}ซึ่งมีค่าเป็นช่องว่างเดียว คุณสามารถใช้เพื่อแทรกช่องว่างที่จะไม่ถูกตัดโดยอัตโนมัติเช่นนี้:${space} <td>foo${space}${space}${space}</td>เราได้รวมตัวแปรไว้ ${nbsp}ด้วยซึ่งคุณสามารถใช้เพื่อแทรกช่องว่างที่ไม่ทำลาย

โปรดทราบว่า XPaths ไม่ได้ทำให้ช่องว่างเป็นปกติเหมือนที่เราทำ หากคุณต้องการที่จะเขียน XPath เหมือน //div[text()="hello world"]แต่ HTML ของการเชื่อมโยงที่เป็นจริง " hello&nbsp;world" คุณจะต้องใส่จริง " &nbsp;" ในกรณีทดสอบ Selenese //div[text()="hello${nbsp}world"]ของคุณจะได้รับมันให้ตรงเช่นนี้


1
ลิงก์ OpenQA ไม่สามารถโหลดได้สำเร็จอีกต่อไป
kjosh

1
ฉันแค่อยากทราบว่า $ {nbsp} ใช้งานไม่ได้สำหรับฉันในเครื่องมือ Selenium หรือ Chrome dev ก็\u00a0เช่นกัน สิ่งที่ทำงานให้ฉันได้รับการพิมพ์เป็นพื้นที่ที่ไม่ทำลายใน Alt+Shift+Spacemac ค้นเว็บบอกว่าAlt+0160บน windows
Cynic

25

ฉันพบว่าฉันสามารถจับคู่ได้เมื่อฉันป้อนช่องว่างที่ไม่ทำลายรหัสยาก (U + 00A0) โดยพิมพ์ Alt + 0160 บน Windows ระหว่างสองเครื่องหมายคำพูด ...

//table[@id='TableID']//td[text()=' ']

ทำงานให้ฉันด้วยถ่านพิเศษ

จากสิ่งที่ฉันเข้าใจมาตรฐาน XPath 1.0 ไม่ได้จัดการกับอักขระ Unicode ที่หลบหนี ดูเหมือนว่าจะมีฟังก์ชันสำหรับสิ่งนั้นใน XPath 2.0 แต่ดูเหมือนว่า Firefox จะไม่รองรับ (หรือฉันเข้าใจผิดบางอย่าง) ดังนั้นคุณต้องทำกับโค้ดเพจท้องถิ่น น่าเกลียดฉันรู้

จริงๆแล้วดูเหมือนว่ามาตรฐานจะใช้ภาษาโปรแกรมโดยใช้ XPath เพื่อจัดเตรียมลำดับการหลีกเลี่ยง Unicode ที่ถูกต้อง ... ดังนั้นฉันทำสิ่งที่ถูกต้องแล้ว


การใช้ Xpather 1.4.1 ใน Firefox 2 // td [text () = ''] ไม่ให้ผลลัพธ์
Zack The Human

ขอโทษ มันไม่ได้ผลสำหรับฉัน เป้าหมายสุดท้ายของฉันคือใช้มันในซีลีเนียมสำหรับการทดสอบอินเทอร์เฟซเว็บของฉัน ซีลีเนียมเองจะเก็บนิพจน์ทดสอบไว้ในโครงสร้าง XML และการพิมพ์ Alt Windows ดูเหมือนจะหายไประหว่างทาง นอกจากนี้ & # 160; ของฉัน ส่งคืนเป็นใน XML
Bergeroy

Zack ตามที่ฉันเขียนคุณต้องแทนที่ช่องว่างระหว่างเครื่องหมายคำพูดทั้งสองด้วยอักขระที่สร้างโดย Alt + 0160 (บนแป้นพิมพ์ตัวเลข)
PhiLho

4
ต้องทำงานนี้กับ PHP ให้สำเร็จด้วย:$col = $xpath->query("//p[text()=\"\xC2\xA0\"]");
hakre

@Bergory สิ่งนี้ใช้งานได้โดยใช้ Protractor พร้อมไดรเวอร์ Selenium
Damian Green

4

ลองใช้เอนทิตีทศนิยม&#160;แทนเอนทิตีที่มีชื่อ หากไม่ได้ผลคุณควรใช้อักขระ Unicode สำหรับช่องว่างที่ไม่ทำลายแทน&nbsp;เอนทิตี

(หมายเหตุ: ฉันไม่ได้ลองใน XPather แต่ฉันได้ลองใน Oxygen)


1

จำไว้ว่าหน่วยประมวลผล XML มาตรฐานจะได้เข้ามาแทนที่การอ้างอิงนิติบุคคลอื่นใดนอกเหนือจาก XML ของคนมาตรฐานห้า ( &amp;, &gt;, &lt;, &apos;, &quot;) ที่มีตัวอักษรที่สอดคล้องกันในการเข้ารหัสเป้าหมายโดยการแสดงออกเวลา XPath มีการประเมิน ด้วยพฤติกรรมดังกล่าวคำแนะนำของ PhiLho และ jsulak จึงเป็นหนทางที่จะไปหากคุณต้องการทำงานกับเครื่องมือ XML เมื่อคุณป้อน&#160;ในนิพจน์ XPath ควรแปลงเป็นลำดับไบต์ที่เกี่ยวข้องก่อนที่จะใช้นิพจน์ XPath


1
ไม่ใช่ถ้าคุณลอง / ใช้ XPath ใน XPather (GUI) หรือใน JavaScript (ไม่มีการแทนที่เอนทิตีอัตโนมัติเนื่องจากเราไม่ได้อยู่ใน XML) คำแนะนำที่ดีในสภาพแวดล้อม XML อื่น ๆ (XSTL?)
PhiLho

1

ตาม HTML ที่คุณให้ไว้:

<tr>
  <td>abc</td>
  <td>&nbsp;</td>
</tr>

ในการค้นหาโหนดด้วยสตริง&nbsp;คุณสามารถใช้สิ่งใดสิ่งหนึ่งต่อไปนี้ โซลูชันที่ใช้:

  • ใช้text():

    "//td[text()='\u00A0']"
  • ใช้contains():

    "//td[contains(., '\u00A0')]"

อย่างไรก็ตามคุณอาจต้องการหลีกเลี่ยงอักขระNO-BREAK SPACEและใช้กลยุทธ์ Locatorอย่างใดอย่างหนึ่งต่อไปนี้:

  • การใช้<tr>โหนดหลักและfollowing-sibling:

    "//tr//following-sibling::td[2]"
  • ใช้starts-with():

    "//tr//td[last()]"
  • การใช้<td>โหนดก่อนหน้าและการfollowingnode andติดตามพี่น้อง:

    "//td[text()='abc']//following::td[1]"

การอ้างอิง

คุณสามารถค้นหาการอภิปรายโดยละเอียดที่เกี่ยวข้องได้ใน:


TL; ดร

อักขระ Unicode 'NO-BREAK SPACE' (U + 00A0)


0

ฉันไม่สามารถจับคู่โดยใช้ Xpather ได้ แต่สิ่งต่อไปนี้ใช้ได้กับฉันกับไฟล์ XML และ XSL ธรรมดาใน XML Notepad ของ Microsoft:

<xsl:value-of select="count(//td[text()='&nbsp;'])" />

ค่าที่ส่งคืนคือ 1 ซึ่งเป็นค่าที่ถูกต้องในกรณีทดสอบของฉัน

อย่างไรก็ตามฉันต้องประกาศว่าnbspเป็นเอนทิตีภายใน XML และ XSL ของฉันโดยใช้สิ่งต่อไปนี้:

<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#160;"> ]>

ผมไม่แน่ใจว่าจะช่วยคุณ แต่ฉันก็สามารถที่จะเป็นจริงพบnbspใช้นิพจน์ XPath

แก้ไข: ตัวอย่างโค้ดของฉันมีอักขระ"& nbsp;" แต่การเน้นไวยากรณ์ของ JavaScript จะแปลงเป็นอักขระช่องว่าง อย่าเข้าใจผิด!


คุณสามารถแก้ไขตัวอย่างโค้ดของคุณได้เหมือนที่ทำกับตัวอย่างในคำถามของฉัน แทนที่เอนทิตี nbsp ของคุณโดย & amp; nbsp;
Bergeroy

0

ค้นหา&nbsp;หรืออย่างเดียวnbsp- คุณลองสิ่งนี้ไหม


ฉันรู้ว่าสิ่งนี้ควรได้ผล แต่ก็ไม่แน่ใจในสิ่งที่ฉันพบ ต้องมีวิธีใน XPATH ในการเข้ารหัสวิธีที่แน่นอนเพื่อให้ตรงกับสิ่งที่ฉันกำลังมองหา
Bergeroy

บางทีฉันควรมองไปที่การแสดงออกปกติ
Bergeroy

-2

คุณสามารถใช้, XPath ประกอบด้วย, Sibling, Ancestor Functions ใน Selenium WebDriver เพื่อค้นหาองค์ประกอบที่ไม่มีคุณสมบัติพิเศษใด ๆ ให้ระบุ

สำหรับรายละเอียดเพิ่มเติมโปรดอ่านหน้านี้: https://www.guru99.com/using-contains-sbiling-ancestor-to-find-element-in-selenium.html

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.