IT story

XPath contains (text (), 'some string')은 둘 이상의 Text 하위 노드가있는 노드와 함께 사용할 때 작동하지 않습니다

hot-time 2020. 4. 15. 12:35
반응형

XPath contains (text (), 'some string')은 둘 이상의 Text 하위 노드가있는 노드와 함께 사용할 때 작동하지 않습니다


Xpath에 dom4j에 포함 된 작은 문제가 있습니다 ...

내 XML이

<Home>
    <Addr>
        <Street>ABC</Street>
        <Number>5</Number>
        <Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment>
    </Addr>
</Home>

루트 요소가 주어진 텍스트에서 ABC가있는 모든 노드를 찾고 싶다고 가정 해 보겠습니다.

그래서 내가 쓸 필요가있는 xpath는

//*[contains(text(),'ABC')]

그러나 이것은 Dom4j가 반환하는 것이 아닙니다 .... 이것이 dom4j 문제 또는 xpath 작동 방식을 이해하는 것입니다. 이 쿼리는 Comment 요소가 아닌 Street 요소 만 반환하므로

DOM은 Comment 요소를 4 개의 태그가 2 인 복합 요소로 만듭니다.

[Text = 'XYZ'][BR][BR][Text = 'ABC'] 

나는 요소를 찾아서 실행해야하기 때문에 쿼리가 여전히 요소를 반환해야한다고 가정하지만 ... ...

다음 쿼리는 요소를 반환하지만 요소보다 훨씬 더 많이 반환하고 부모 요소도 반환합니다 ... 문제에 바람직하지 않습니다 ...

//*[contains(text(),'ABC')]

하나는 바로 요소 반환 XPath 쿼리 알고 있나요 <Street/><Comment/>?


<Comment>태그는 두 개의 텍스트 노드와이 개 포함 <br>자식으로 노드를.

당신의 xpath 표현은

//*[contains(text(),'ABC')]

이것을 분해하기 위해

  1. * 모든 요소 (예 : 태그)와 일치하는 선택기입니다. 노드 세트를 반환합니다.
  2. []노드 세트 내의 각각의 노드에서 동작하는 조건이다. 작동하는 개별 노드 중 하나가 대괄호 안의 조건과 일치하면 일치합니다.
  3. text()컨텍스트 노드의 하위 인 모든 텍스트 노드와 일치 하는 선택기 입니다. 노드 세트를 반환합니다.
  4. contains문자열에서 작동하는 함수입니다. 노드 세트가 전달되면 노드 세트 에서 문서 순서로 첫 번째 인 노드의 문자열 값을 리턴 하여 노드 세트를 문자열로 변환 합니다. 따라서 <Comment>요소 의 첫 번째 텍스트 노드와 만 일치 할 수 있습니다 BLAH BLAH BLAH. 일치하지 않기 때문에 <Comment>결과를 얻지 못합니다 .

이것을 다음으로 변경해야합니다

//*[text()[contains(.,'ABC')]]
  1. * 모든 요소 (예 : 태그)와 일치하는 선택기입니다. 노드 세트를 반환합니다.
  2. 바깥 쪽 []은 해당 노드 세트의 각 개별 노드에서 작동하는 조건부입니다. 여기서 문서의 각 요소에서 작동합니다.
  3. text()컨텍스트 노드의 하위 인 모든 텍스트 노드와 일치 하는 선택기 입니다. 노드 세트를 반환합니다.
  4. 내부 []는 해당 노드 세트의 각 노드 (여기서는 개별 텍스트 노드)에서 작동하는 조건부입니다. 각 개별 텍스트 노드는 괄호 안에있는 경로의 시작점이며 괄호 안에 명시 적으로 참조 될 수도 있습니다 .. 작동하는 개별 노드 중 하나가 대괄호 안의 조건과 일치하면 일치합니다.
  5. contains문자열에서 작동하는 함수입니다. 여기에는 개별 텍스트 노드 ( .) 가 전달 됩니다. <Comment>태그 의 두 번째 텍스트 노드가 개별적 으로 전달되므로 'ABC'문자열 을보고 일치시킬 수 있습니다.

[contains(text(),'')]true 또는 false 만 반환합니다. 어떤 요소 결과도 반환하지 않습니다.


시간이 조금 걸렸지 만 마침내 알아 냈습니다. 아래 텍스트가 포함 된 사용자 정의 xpath가 완벽하게 작동했습니다.

//a[contains(text(),'JB-')]

XML 문서 :

<Home>
    <Addr>
        <Street>ABC</Street>
        <Number>5</Number>
        <Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment>
    </Addr>
</Home>

XPath 표현식 :

//*[contains(text(), 'ABC')]

//*루트 노드모든 하위 요소 와 일치 합니다 . 즉, 루트 노드 이외의 모든 요소입니다.

[...]A는 술어 , 그것은 노드 집합을 필터링합니다. 하는 것은 노드를 반환하는 ...것입니다 true:

술어는 노드 세트 [...]를 필터링하여 새 노드 세트를 생성합니다. 필터링 된 노드 집합의 각 노드에 대해 PredicateExpr이 평가됩니다 [...]; PredicateExpr이 해당 노드에 대해 true로 평가되면 해당 노드는 새 노드 세트에 포함됩니다. 그렇지 않으면 포함되지 않습니다.

contains('haystack', 'needle')포함하는true 경우를 반환 합니다 .haystack needle

함수 : 부울 포함 (문자열, 문자열)

contains 함수는 첫 번째 인수 문자열에 두 번째 인수 문자열이 포함되어 있으면 true를 반환하고 그렇지 않으면 false를 반환합니다.

그러나 contains()문자열을 첫 번째 매개 변수로 사용합니다. 그리고 그것은 통과 된 노드입니다. 이를 처리하기 위해 첫 번째 매개 변수로 전달 된 모든 노드 또는 노드 세트 함수에 의해 문자열로 변환 됩니다 string().

문자열 함수를 호출하여 인수가 문자열 유형으로 변환됩니다.

string()첫 번째 노드string-value함수 반환 :

노드 세트는 문서 순서에서 첫 번째 인 노드 세트에있는 노드의 문자열 값을 리턴하여 문자열로 변환됩니다. 노드 집합이 비어 있으면 빈 문자열이 반환됩니다.

string-value요소 노드 :

요소 노드의 문자열 값은 문서 노드에서 요소 노드의 모든 텍스트 노드 자손의 문자열 값을 연결 한 것입니다.

string-value(A)의 텍스트 노드 :

텍스트 노드의 문자열 값은 문자 데이터입니다.

따라서 기본적으로 string-value노드에 포함 된 모든 텍스트 (모든 자손 텍스트 노드의 연결)입니다.

text() 모든 텍스트 노드와 일치하는 노드 테스트입니다.

모든 텍스트 노드에 대해 노드 테스트 text ()가 true입니다. 예를 들어 child :: text ()는 컨텍스트 노드의 텍스트 노드 자식을 선택합니다.

이 말을 //*[contains(text(), 'ABC')]하면 첫 번째 텍스트 노드가 포함하는 모든 요소 (그러나 루트 노드)와 일치합니다 ABC. text()컨텍스트 노드의 모든 하위 텍스트 노드가 포함 된 노드 세트를 리턴 하므로 (표현식에 상대적) 그러나 contains()첫 번째 것만 취합니다. 따라서 위의 문서의 경우 경로가 Street요소 와 일치합니다 .

다음 표현식 //*[text()[contains(., 'ABC')]]은 하나 이상의 하위 텍스트 노드가 있고을 포함하는 모든 요소 (그러나 루트 노드)와 일치합니다 ABC. .컨텍스트 노드를 나타냅니다. 이 경우 루트 노드를 제외한 모든 요소의 하위 텍스트 노드입니다. 따라서 위의 문서에서 경로는 StreetComment요소 일치합니다 .

이제 하위 텍스트 노드의 연결에 //*[contains(., 'ABC')]포함 된 모든 요소 (그러나 루트 노드)와 일치합니다 ABC. 가 일치 위의 문서 HomeAddrStreet, 그리고 Comment요소를. 따라서, //*[contains(., 'BLAH ABC')]성냥 HomeAddr,와 Comment요소를.

참고 URL : https://stackoverflow.com/questions/3655549/xpath-containstext-some-string-doesnt-work-when-used-with-node-with-more

반응형