2013-07-16 4 views
3

매번 549 자의 텍스트를 얻을 XPath 쿼리를 만들려고합니다. 텍스트는 관련 주제에 관한 것이어야합니다. 아래 예에서는 oranges 또는 apples 또는 pears입니다. 페이지에 이러한 단어가 포함 된 요소가 없으면 XPath 쿼리에서 페이지의 특정 텍스트를보다 쉽게 ​​찾을 수있게하고 싶습니다.특정 길이의 텍스트를 가져 오는 XPath

명확한 설명을 위해, 특정 종류의 텍스트를 포함하는 요소를 찾는 XPath 쿼리를 만들려고합니다. 아래 쿼리를 사용하여 549 개 이상의 문자를 찾았다면 아무 것도 발견되지 않거나 반환 된 텍스트가 549 문자보다 작습니다. XPath 쿼리에서 단락 서식에있는 페이지의 텍스트를 가져오고 싶습니다 (버튼, 링크, 메뉴 등의 텍스트를 제외하고는 아무 것도 작동하지 않습니다).이 텍스트의 549자를 반환합니다. 결과 문자열이 549 자 미만인 경우 다음 두 쿼리를 연결하고 싶습니다. 중간에 ....

substring(normalize-space(//*[self::p or self::div][contains(text(),'apples') or contains(text(),'oranges') or contains(text(),'pears')]), 0, 549) 

나는 이것을 잠시 동안 작동 시키려고 노력해 왔으며 어떤 제안이라도 고맙게 생각합니다!

미리 감사드립니다.

답변

5

예.

substring(normalize-space(//*[string-length(text()) > 549 and (... other conditions ...)]),0,549) 

페이지의 "Is there an "if -then - else " statement in XPath?"당신이 줄임표를 추가 할 필요가 있는지 확인하는 조건문을 수행하는 방법에 대한 : 당신이 당신의 조건에서 사용할 수있는 XPath에있는 string-length() 기능이있다. 위의 SO 질문에서 예를 적응

:

if (fn:string-length(normalize-space(//*[self::p or self::div][contains(text(),'apples']) > 549) 
     then (concat(fn:substring(normalize-space(//*[self::p or self::div][contains(text(),'apples']), 0, 5490), "...")) 
     else (normalize-space(//*[self::p or self::div][contains(text(),'apples'])) 

이 정말 XPath는 복잡 할 날 것으로 보인다. 당신이 XQuery를 사용할 수있는 경우에, 당신은 훨씬 더 읽기 변환해야합니다 :

for $text in normalize-space(//*[self::p or self::div]) 
where $text[contains(text(),'apples' or ...] 
return 
    if (string-length($text) > 549) then 
     concat(substring($text, 0, 549), "...") 
    else 
     $text 

을 나는이 실제로 더 여러과 (가독성, 유지 보수) 최적화 된 다양한 과일을 다루는 문에 대한 중첩 될 수 있습니다 생각하면 필요한 것.

XSL을 사용하는 경우 :

는 는
<xsl:template match="//*[self::p or self::div][contains(text(),'apples' or ...]"> 
    <xsl:variable name="text" select="normalize-space(.)" /> 
    <xsl:choose> 
     <xsl:when test="string-length($text)"> 
      <xsl:value-of select="substring($text, 0, 549)"/>... 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$text"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
는 은 또한 정규 표현식 구성하여, 많은 contains() 조건을 가진 방지하기 위해 matches() XPath는 기능을 사용할 수 있습니다

: 마지막으로

matches(//*[self::p or self::div][matches(text(),'(apples|oranges|bananas)']) 

을 알고 있어야 XPath에 //*을 사용하면 매우 비효율적이며 문서에 어떤 가중치가있을 경우 성능에 영향을 미칩니다. 나는 이것을 최적화하는 방법이 있다는 것을 알리는 가려움이 있지만, 불행히도 나는 연구 할 시간이 없다.

+0

+1 답장을 보내 주셔서 감사합니다. 나는 문자열 길이 함수에 대해 몰랐다. 이 예제를 사용하여 false 일 경우 하나의 XPath 쿼리를 적용하는 방법에 대한 기본 예제를 보여줄 수 있습니까? – AnchovyLegend

관련 문제