2012-05-01 2 views
5

XPath를 사용하여 "전체 단어 일치"(VS 검색과 마찬가지로 사용자에게 옵션)를 사용하고 싶습니다.XPath : 전체 단어 일치 (대/소문자를 구분하지 않는 플래그가있는 matches 함수 사용)

마치 일치하면 대소 문자를 구분하지 않기 위해 i과 같은 플래그를 허용하지만 기능이 containsmatches 인 것처럼 보입니다.

<pets> 
    <dog name="Rupert" color="grey"/> 
    <dog name="Ralph" color="brown"/> 
    <cat name="Marvin the Cat" color="white"/> 
    <cat name="Garfield the Cat" color="orange"/> 
    <cat name="Cat" color="grey"/> 
    <cat name="Fluffy" color="black"/> 
</pets> 

Matches XPath: //cat[descendant-or-self::*[@*[matches(.,'Cat')]]] 
    returns: 
    <cat name="Marvin the Cat" color="white"/> 
    <cat name="Garfield the Cat" color="orange"/> 
    <cat name="Cat" color="grey"/> 


Contains XPath: //cat[descendant-or-self::*[@*[contains(.,'Cat')]]] 
    returns: 
    <cat name="Marvin the Cat" color="white"/> 
    <cat name="Garfield the Cat" color="orange"/> 
    <cat name="Cat" color="grey"/> 

하지만 난 단지 "고양이"전체 단어와 일치하는 결과를 반환하는 matches를 사용하고 싶습니다 : : 즉

, 나는이 두 XPath 쿼리와 동일한 결과를 얻고있다

<cat name="Cat" color="grey"/> 

전체 단어와 일치하도록 일치 검색어를 어떻게 조정할 수 있습니까?

EDIT : 대소 문자를 구분하지 않아도되므로 대/소문자를 구분하는 기능을 사용해야합니다.

답변

5

^$자를 앵커로 사용하면 어떨까요? RegEx Syntax in XQuery 1.0 and XPath 2.0에서

//cat[descendant-or-self::*[@*[matches(.,'^Cat$')]]] 

:

두 메타 문자, ^$이 추가됩니다. 기본적으로 ^ 메타 문자는 전체 문자열의 시작과 일치하지만 $은 전체 문자열 의 끝에 부합합니다.

+0

흠 .. 이것은 내가 원하는 결과를 준다. 하지만^$ 앵커에 대해 설명해 주시겠습니까? 나는 전에 그들을 사용한 적이 없다. – developer

+0

"2 개의 메타 - 캐릭터 ..."섹션을 참조하여 답변을 추가했다. –

+1

감사합니다. 아직 테스트를해야 할 것입니다.하지만이 트릭을 수행하는 것 같습니다! – developer

2

이 기능을 사용할 수 있습니까?

//cat[@*='Cat'] 
+0

내가 원하는 것은 아닙니다. 대소 문자를 구분할 필요가 없기 때문에 matches 함수를 사용하고 싶습니다 ... (위의 편집 참조). – developer

1

이 :에

//cat[@*='Cat'] 

결과 :

<cat name="Cat" color="grey"/> 

나는 Xacobeo를 사용하여 검증 하였다.

+0

내가 뭘 찾고 있는지 모르겠다. 대소 문자를 구분할 필요가 없기 때문에 matches 함수를 사용하고 싶습니다 ... (위의 편집 참조). – developer

+1

이 시도 @developer : '// 고양이 [번역 (@ * 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') = '고양이']' 이 항상 소문자로하여 일치시킬 문자열을 전달 가정합니다. –

2

여기에는 세 가지 기능/관련 연산자가 있습니다.

matches()는 정규식 일치를 수행합니다. 하위 문자열을 일치 시키거나 앵커 (^ cat $)를 사용하여 전체 문자열을 일치시키는 데 사용할 수 있으며 'i'플래그를 설정하여 대소 문자를 구분할 수 있습니다.

contains()는 부분 문자열을 정확하게 일치시킵니다. 세 번째 인수 (데이터 정렬)를 사용하여 대/소문자 일치를 요청할 수 있지만 데이터 정렬이 지정되는 방식은 사용중인 프로세서에 따라 다릅니다.

eq 연산자는 전체 문자열과 정확히 일치합니다. XPath의 경우 프로세서의 API를 사용하여 일반적으로 설정되는 "기본 데이터 정렬"을 사용하여 대소 문자를 구분할 수 있습니다.이것은 귀하의 요구 사항에 가장 가까운 것으로 보이지만 유일한 단점은 matches()에 "i"플래그를 사용하는 것보다 데이터 정렬을 지정하는 것이 시스템 종속적이라는 것입니다.

2

하지만 난 단지 "고양이" 전체 단어와 일치하는 결과를 반환하는 일치를 사용하고 싶습니다 :

<cat name="Cat" color="grey"/> 

가 원하는 요소를 선택 서로 다른 XPath 표현식이 있습니다

사용 :

/*/cat[matches(@name, '^cat$', 'i')] 

또는 사용 :

/*/cat[lower-case(@name) eq 'cat'] 

XSLT - 기반의 검증 :

<pets> 
    <dog name="Rupert" color="grey"/> 
    <dog name="Ralph" color="brown"/> 
    <cat name="Marvin the Cat" color="white"/> 
    <cat name="Garfield the Cat" color="orange"/> 
    <cat name="Cat" color="grey"/> 
    <cat name="Fluffy" color="black"/> 
</pets> 

이 변환이 두 XPath를 평가 : 제공된 XML 문서에 적용

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "/*/cat[matches(@name, '^cat$', 'i')]"/> 
====== 
    <xsl:copy-of select= 
    "/*/cat[lower-case(@name) eq 'cat']"/> 

</xsl:template> 
</xsl:stylesheet> 

표현과 복사 선택한 요소를 출력에 연결 :

<cat name="Cat" color="grey"/> 
====== 
    <cat name="Cat" color="grey"/>