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>
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>
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, '')) > 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>
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
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
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órysąw $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.
@_marko: Czy przeczytałeś moją odpowiedź i czy było to dla ciebie przydatne? –
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 *. –