2011-12-05 18 views
5

Sth powinno być wszystkimi literami lub wyrażeniami regularnymi [A-Z]. Jak połączyć xslt z wyrażeniami regularnymi?Jak napisać xslt, jeśli element zawiera litery?

<xsl:if test="string-contains(//ns0:elem/value, 'sth')"> 


     </xsl:if> 
+0

@_marko: Czy przeczytałeś moją odpowiedź i czy było to dla ciebie przydatne? –

+0

Właśnie zaktualizowałem odpowiedź za pomocą drugiego wyrażenia XPath i pełnego przykładu kodu, który demonstruje oba wyrażenia XPath 1.0 - pierwszy z użyciem metody * double-translate *. –

Odpowiedz

9

XPath/XSLT 1.0 nie obsługuje wyrażeń regularnych, ale proste sprawdzanie poprawności może być wykonywane przy użyciu podstawowych funkcji łańcuchowych.

whitelisting

XPath 1,0 translate funkcja może być wykorzystywana do symulacji whitelist:

<xsl:variable name="alpha" 
       select="'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> 
<xsl:if test="string-length(translate(., $alpha, '')) &gt; 0"> 
    <!-- context node contains non-alpha characters --> 
</xsl:if> 

Test wykorzystuje translate usunięcie wszystkich górny i dolny litery.Jeśli wynikowa długość łańcucha jest różna od zera, oryginalny ciąg musi zawierać dodatkowe znaki.

Należy zauważyć, że powyższe wyrażenie można uprościć do:

<xsl:if test="translate(., $alpha, '')"> 

... bo każdy niepusty ciąg wartość true.

Czarne listy

pomocą metody podwójnego przełożyć do leczenia $alpha postaci czarnej listy:

<xsl:if test="translate(., translate(., $alpha, ''), '')"> 
    <!-- context-node contains characters on the blacklist (in $alpha) --> 
</xsl:if> 

Wewnętrzna translate powraca ciąg z usunięte wszystkie jego znaki alfa, który jest następnie wykorzystywany jako szablon do drugiego wywołania translate, w wyniku czego łańcuch zawiera tylko znaki alfanumeryczne. Jeśli ten ciąg nie jest zerem, to znaleźliśmy znak na czarnej liście. To klasyczne podejście. Patrz, na przykład, to poprzednie pytanie na SO:

Test czarna lista może być również wykonywana tak:

not(string-length(translate(., $alpha, ''))=string-length()) 

Jeśli długość łańcucha po usunięciu wszystkich na czarnych listach znaków nie jest równa długości oryginalnego napisu, wtedy ciąg musi zawierać znak na czarnej liście.

Podsumowanie

Blacklisty i białe listy są naprawdę dwie strony tego samego medalu. Poniższe przykłady ilustrują ich użycie:

<xsl:if test="translate(., $alpha, '')"> 
    [contains some characters not on the list] 
</xsl:if> 
<xsl:if test="not(translate(., $alpha, ''))"> 
    [contains only characters on the list] 
</xsl:if> 
<xsl:if test="translate(., translate(., $alpha, ''), '')"> 
    [contains some characters on the list] 
</xsl:if> 
<xsl:if test="not(translate(., translate(., $alpha, ''), ''))"> 
    [contains only characters not on the list] 
</xsl:if> 
2

W XPath 1.0 (współpracuje z XSLT 1.0), nie masz narzędzia do regex (trzeba tylko funkcje jak contains lub starts-with, patrz link poniżej, aby uzyskać więcej informacji)

W XPATH 2.0 (działa z XSLT 2.0), masz funkcję matches i funkcję replace (patrz link poniżej).

URL, aby zobaczyć:

XPath 1.0 funkcje łańcuchowe: http://www.w3.org/TR/xpath/#section-String-Functions

XPath 2.0 regex funkcje: http://www.w3.org/TR/xpath-functions/#string.match

+1

Mam rozwiązanie i używam wersji 1.0. Jak szukać liter w łańcuchu, jeśli nie możesz użyć wyrażenia regularnego w xslt? – marko

2

Jak szukać liter w ciągu znaków, jeśli nie można użyć wyrażenia regularnego w xslt?

Dobre pytanie, +1.

Zastosowanie:

translate(., translate(., $vAlpha, ''), '') 

To produkuje wszystkie znaki w wartości ciągu bieżącego węzła, któryw $vAlpha

W przypadku, gdy chcesz sprawdzić, czy dany ciąg $str zawiera tylko litery i nie ma innej postaci, użyj :

string-length(translate($str, $vAlpha, '')) = 0 

Kompletny przykładowy kod:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:variable name="vUpper" select= 
    "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> 

<xsl:variable name="vLower" select= 
    "'abcdefghijklmnopqrstuvwxyz'"/> 

<xsl:variable name="vAlpha" select= 
     "concat($vUpper, $vLower)"/> 

<xsl:variable name="vStr" select="'A12B_..c02d'"/> 

<xsl:template match="/"> 
    <xsl:value-of select= 
    "translate($vStr, 
       translate($vStr, $vAlpha, ''), '') 
    "/> 


    The string <xsl:value-of select="$vStr"/> has <xsl:text/> 
    <xsl:value-of select= 
    "string-length(translate($vStr, $vAlpha, ''))"/> <xsl:text/> 
    non-letters 

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

kiedy ta transformacja jest stosowana na dowolnym dokumencie XML (nie używany), przy czym poszukiwany, poprawny wynik jest produkowany:

ABcd 


    The string A12B_..c02d has 7 
    non-letters 

Zapamiętaj: Pierwsze wyrażenie XPath powyżej demonstruje tak zwaną "podwójnie przetłumaczoną metodę" "", po raz pierwszy zaproponowaną przez Michaela Kaya.

Powiązane problemy