2012-05-01 9 views
5

Używając XPath, chciałbym "Dopasować całe słowo" (opcja dla użytkownika, podobnie jak w wyszukiwaniu VS).XPath: Dopasuj całe słowo (używając funkcji dopasowywania z flagą niewrażliwą na wielkość znaków)

Wygląda na to, że funkcje działają podobnie, mimo że dopasowania pozwalają na takie znaczniki jak i dla rozróżniania wielkości liter.

Innymi słowy, ja dostaję te same wyniki z tymi zapytaniami dwa XPath:

<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"/> 

Ale chciałbym użyć matches aby powrócić wyników, które pasują „Cat” cały tylko słowo:

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

Jak dopasować zapytanie dopasowania tak, aby pasowało do całego słowa?

EDYCJA: Zapomniałem wspomnieć, że muszę nadal używać funkcji dopasowania, ponieważ potrzebuję flagi niewrażliwości na wielkość liter.

Odpowiedz

5

Co ze znakami ^ i $ jako kotwicami?

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

Od RegEx Syntax in XQuery 1.0 and XPath 2.0:

Dwa meta-znaków, ^ i $ dodaje. Domyślnie meta-znak jest dopasowany do początku całego łańcucha, podczas gdy $ dopasowuje koniec całego ciągu znaków.

+0

Hmm ... to daje mi pożądany rezultat. Ale czy mógłbyś wyjaśnić kotwice^$? Nigdy ich wcześniej nie użyłem. – developer

+0

Dodałem link do odpowiedzi, zobacz sekcję "Dwa meta-znaki ...". –

+1

Dzięki, nadal będę musiał przeprowadzić pewne testy, ale to chyba wystarczy! – developer

2

Czy ta praca jest dla Ciebie?

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

Nie do końca tego, czego szukam. Nadal chcę korzystać z funkcji dopasowywania, ponieważ potrzebuję rozróżniania wielkości liter ... (patrz edycja powyżej). – developer

1

to:

//cat[@*='Cat'] 

skutkuje:

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

zweryfikowany za pomocą Xacobeo.

+0

Nie do końca tego, czego szukam. Nadal chcę korzystać z funkcji dopasowywania, ponieważ potrzebuję rozróżniania wielkości liter ... (patrz edycja powyżej). – developer

+1

@developer Spróbuj tego: '// kot [translate (@ *, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'kot']' Zakłada zawsze przechodzą ciąg, który chcesz dopasować przez tak małe. –

2

Istnieją tutaj trzy funkcje/operatory.

matches() wykonuje dopasowanie wyrażenia regularnego; możesz go użyć do dopasowania podłańcucha lub do dopasowania całego łańcucha za pomocą kotwic (^ cat $), i możesz ustawić flagę "i", aby była niewidoczna.

Zawiera() dokładnie dopasowuje podciąg; możesz użyć trzeciego argumentu (sortowanie), aby zażądać dopasowania po zamknięciu sprawy, ale sposób określania sortowania zależy od używanego procesora.

Operator eq wykonuje dokładne dopasowanie całego ciągu znaków; "domyślne sortowanie" (które w przypadku XPath będzie zazwyczaj ustawiane za pomocą interfejsu API procesora) może być używane do żądania dopasowania z uwzględnieniem przypadku.Wygląda na to, że jest najbliższy twoim wymaganiom, jedyną wadą jest to, że określanie sortowania jest bardziej zależne od systemu niż użycie flagi "i" z dopasowaniami().

2

Ale chciałbym używać zapałek, aby powrócić wyników, które pasują „Cat” cały tylko słowo:

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

Istnieją różne wyrażenie XPath, które wybrać żądaną elementu:

Zastosowanie:

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

lub użyj:

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

XSLT - na podstawie weryfikacji:

<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> 

po naniesieniu na dostarczonych dokumentów XML:

<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> 

ta przemiana ocenia dwa XPath wyrażeń i kopiuje wybrane elementy na wyjściu:

<cat name="Cat" color="grey"/> 
====== 
    <cat name="Cat" color="grey"/> 
Powiązane problemy