XPATH를 사용하여 & nbsp;


120

나는 사용한다 XPather 브라우저 를 하여 HTML 페이지에서 내 XPATH 표현식을 확인합니다.

내 최종 목표는 내 사용자 인터페이스 테스트를 위해 Selenium에서 이러한 표현식을 사용하는 것입니다.

다음과 유사한 내용의 HTML 파일이 있습니다.

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

문자열 " &nbsp;"이 포함 된 텍스트가있는 노드를 선택하고 싶습니다 .

"abc"와 같은 일반 문자열에는 문제가 없습니다. 나는 //td[text()="abc"].

XPATH로 시도하면 //td[text()="&nbsp;"]아무것도 반환하지 않습니다. " &"가있는 텍스트에 관한 특별한 규칙이 있습니까?


실제 XSL 변환이 아무것도 반환하지 않습니까? 아니면 Xpather 만?
Zack The Human

답변:


89

Selenium 뒤에 있는 OpenQA 는 이미이 문제를 해결 한 것 같습니다. 그들은 공백을 명시 적으로 일치시키기 위해 몇 가지 변수를 정의했습니다. 제 경우에는 다음과 유사한 XPATH를 사용해야합니다.//td[text()="${nbsp}"] .

이 문제에 관한 OpenQA의 텍스트를 여기에서 재현했습니다 ( 여기에 있음 ).

HTML은 요소 내의 공백을 자동으로 정규화하여 선행 / 후행 공백을 무시하고 추가 공백, 탭 및 줄 바꿈을 단일 공백으로 변환합니다. Selenium은 페이지에서 텍스트를 읽을 때이 동작을 복제하려고 시도하므로 HTML의 모든 탭과 줄 바꿈을 무시하고 텍스트가 렌더링 될 때 브라우저에서 어떻게 보이는지에 따라 어설 션을 수행 할 수 있습니다. 눈에 보이지 않는 모든 공백 (비 분리 공백 " &nbsp;"포함)을 단일 공백으로 대체하여이를 수행 합니다. 보이는 모든 줄 바꿈 ( <br>, <p><pre>서식있는 줄 바꿈)은 유지되어야합니다.

HTML Selenese 테스트 케이스 테이블의 텍스트에 동일한 정규화 로직을 사용합니다. 여기에는 여러 가지 장점이 있습니다. 첫째, 당신의 주장이 무엇인지 파악하기 위해 페이지의 HTML 소스를 볼 필요가 없습니다. " &nbsp;"기호는 최종 사용자에게 보이지 않으므로 Selenese 테스트를 작성할 때 기호에 대해 걱정할 필요가 없습니다. ( " &nbsp;"을 포함하는 필드에 대해 assertText를 표시하기 위해 테스트 케이스 에 " "마커 를 넣을 필요가 없습니다 &nbsp;.) Selenese <td>태그 에 추가 줄 바꿈과 공백을 넣을 수도 있습니다 . 테스트 케이스에서 텍스트와 동일한 정규화 논리를 사용하기 때문에 어설 션과 추출 된 텍스트가 정확히 일치하는지 확인할 수 있습니다.

이로 인해 테스트 케이스에 추가 공백을 삽입해야하는 드문 경우에 약간의 문제가 발생합니다. 예를 들어 " foo " 와 같은 필드에 텍스트를 입력해야 할 수 있습니다 . 하지만 단순히 쓰면<td>foo </td> Selenese 테스트 케이스에 추가 공백을 하나의 공백으로 교체합니다.

이 문제에는 간단한 해결 방법이 있습니다. ${space}값이 단일 공백 ​​인 Selenese,에서 변수를 정의했습니다 . 다음 ${space}과 같이 자동으로 잘리지 않는 공백을 삽입하는 데 사용할 수 있습니다 <td>foo${space}${space}${space}</td>. 우리는 또한 변수를 포함했습니다 ${nbsp}끊기지 않는 공백을 삽입하는 데 사용할 수 있습니다.

XPath는 우리가하는 방식으로 공백을 정규화 하지 않습니다 . XPath를 작성해야 //div[text()="hello world"]하지만 링크의 HTML이 실제로 " hello&nbsp;world"인 경우, &nbsp;Selenese 테스트 케이스에 실제 " " 를 삽입 하여 일치 시키려면 다음과 같이해야 //div[text()="hello${nbsp}world"]합니다..


1
OpenQA 링크가 더 이상 성공적으로로드되지 않습니다
kjosh

1
$ {nbsp}가 Selenium 또는 Chrome 개발 도구에서 작동하지 않으며 \u00a0. 나를 위해 일한 것은 mac에서 끊김없는 공백을 입력하는 것이 었습니다 Alt+Shift+Space. 웹 검색은 Alt+0160창에서 말합니다 .
Cynic

25

두 개의 따옴표 사이에 Windows에서 Alt + 0160을 입력하여 하드 코딩 된 비 분리 공백 (U + 00A0)을 입력 할 때 일치 항목을 만들 수 있습니다.

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

특별 문자로 나를 위해 일했습니다.

내가 이해 한 바에 따르면 XPath 1.0 표준은 이스케이프 유니 코드 문자를 처리하지 않습니다. XPath 2.0에 해당 기능이있는 것 같지만 Firefox가 지원하지 않는 것 같습니다 (또는 뭔가 오해 한 것 같습니다). 따라서 로컬 코드 페이지와 관련이 있습니다. 못생긴, 알아.

실제로 표준은 올바른 유니 코드 이스케이프 시퀀스를 제공하기 위해 XPath를 사용하는 프로그래밍 언어에 의존하는 것처럼 보입니다 ... 그래서 어떻게 든 올바른 일을했습니다.


Firefox 2에서 Xpather 1.4.1을 사용하면 // td [text () = ''] 결과가 생성되지 않습니다.
Zack The Human

죄송합니다. 나를 위해 작동하지 않습니다. 내 최종 목표는 웹 인터페이스 테스트를 위해 Selenium에서 사용하는 것입니다. Selenium 자체는 테스트 표현식을 XML 구조로 유지하고 Alt Windows 타이핑이 길을 잃은 것 같습니다. 또한 내 & # 160; XML로 반환됩니다.
Bergeroy

Zack, 내가 쓴 것처럼 두 따옴표 사이의 공백을 Alt + 0160 (숫자 키패드)에 의해 생성 된 문자로 바꿔야합니다.
PhiLho

4
성공적으로뿐만 아니라 PHP와 함께이 일을 할 수있어$col = $xpath->query("//p[text()=\"\xC2\xA0\"]");
hakre

셀레늄 드라이버와 각도기를 사용하여이 작품을 @Bergory
데미안 초록색


2

마음에 베어는 표준을 준수하는 XML 프로세서는 XML의 다섯 개 표준 이외의 어떤 엔티티 참조 (교체 한 것 &amp;, &gt;, &lt;, &apos;, &quot;XPath 식을 평가하는 시간으로 대상 인코딩에서 해당 문자를). 이러한 동작을 감안할 때 PhiLho와 jsulak의 제안은 XML 도구로 작업하려는 경우 갈 수있는 방법입니다. &#160;XPath 표현식 을 입력 하면 XPath 표현식이 적용되기 전에 해당 바이트 시퀀스로 변환되어야합니다.


1
XPather (GUI) 또는 JavaScript (XML이 아니기 때문에 엔티티 자동 대체 없음)에서 XPath를 시도 / 사용하는 경우에는 해당되지 않습니다. 다른 XML 환경 (XSTL?)에서 좋은 조언.
PhiLho

1

Xpather를 사용하여 일치 항목을 얻을 수 없지만 다음은 Microsoft의 XML 메모장에서 일반 XML 및 XSL 파일로 저에게 효과적이었습니다.

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

반환 된 값은 1이며 내 테스트 사례에서 올바른 값입니다.

그러나 다음을 사용하여 nbsp 를 XML 및 XSL 내에서 엔티티 로 선언해야했습니다 .

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

이것이 도움이되는지 확실하지 않지만 실제로 XPath 표현식을 사용하여 nbsp 를 찾을 수있었습니다 .

편집 : 내 코드 샘플에는 실제로 '& nbsp;' 문자가 포함되어 있습니다 . 그러나 JavaScript 구문 강조 표시는 공백 문자로 변환합니다. 오해하지 마십시오!


내 질문의 샘플에서 수행 한 것처럼 코드 샘플을 편집 할 수 있습니다. nbsp 엔티티를 & amp; nbsp;로 바꿉니다.
Bergeroy

1

검색 &nbsp;또는 만 nbsp-시도해 보셨습니까?


나는 이것이 효과가 있다는 것을 알고 있지만 내가 찾은 것이 정확히 확실하지 않습니다. 내가 찾고있는 것과 일치하는 특정 방법을 인코딩하는 방법이 XPATH에 있어야합니다.
Bergeroy

정규 표현식을 살펴 봐야 할 것 같습니다.
Bergeroy

1

제공 한 HTML에 따라 :

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

문자열이있는 노드를 찾으려면 &nbsp; 다음 중 하나를 사용할 수 있습니다. 기반 솔루션 :

  • 사용 text():

    "//td[text()='\u00A0']"
  • 사용 contains():

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

그러나 이상적으로는 NO-BREAK SPACE 문자 를 피하고 다음 로케이터 전략 중 하나를 사용하는 것이 좋습니다 .

  • 부모 <tr>노드 사용 및 following-sibling:

    "//tr//following-sibling::td[2]"
  • 사용 starts-with():

    "//tr//td[last()]"
  • 선행 <td>노드 및 followingnode and다음 형제 사용`:

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

참고

관련 자세한 토론은 다음에서 찾을 수 있습니다.


tl; 박사

유니 코드 문자 'NO-BREAK SPACE'(U + 00A0)


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.