Reputation: 6138
I want to check if a value exists in a sequence defined as
<xsl:variable name="some_seq" select="/root/word[@optional='no']/text()"/>
In the past, I've had success with Priscilla Walmsleys function. For clarity, I reproduce it here as follows:
<xsl:function name="functx:is-value-in-sequence" as="xs:boolean">
<xsl:param name="value" as="xs:anyAtomicType?"/>
<xsl:param name="seq" as="xs:anyAtomicType*"/>
<xsl:sequence select="$value=$seq"/>
</xsl:function>
However, this time I need to make a case-insensitive comparison, and so I tried to wrap both $value
and $seq
with a lower-case()
. Obviously, that didn't help much, as $seq
is a sequence and lower-case()
takes only strings.
Question: what is the best way to either 1) construct a sequence of lower-case strings, or 2) make a case-insensitive comparison analogous to $value=$seq
above? TIA!
Upvotes: 2
Views: 3255
Reputation: 66783
Question: what is the best way to either 1) construct a sequence of lower-case strings
Not many people realize that you can use a function as the last location step in an XPATH 2.0 expression.
You can create a sequence of lower-case()
string values with this expression:
/root/word[@optional='no']/text()/lower-case(.)
or 2) make a case-insensitive comparison analogous to $value=$seq above?
Using that strategy, you can define a custom function that compares the lower-case()
value of the $value
and each string value in the $seq
:
<xsl:function name="functx:is-value-in-sequence" as="xs:boolean">
<xsl:param name="value" as="xs:anyAtomicType?"/>
<xsl:param name="seq" as="xs:anyAtomicType*"/>
<xsl:sequence select="some $word in $seq/lower-case(.)
satisfies ($word = $value/lower-case(.))"/>
</xsl:function>
Upvotes: 3
Reputation: 86774
Use a "for-expression" inside the function to prepare a lower-case version of the sequence
<xsl:variable name="lcseq" select="for $i in $seq return lower-case($i)"/>
See Michael Kay's "XSLT 2.0 and XPATH 2.0, 4th ed", p. 640
(I haven't tested this)
Upvotes: 0