Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Element-in-List testing

Tags:

xslt

For a stylesheet I'm writing (actually for a set of them, each generating a different output format), I have the need to evaluate whether a certain value is present in a list of values. In this case, the value being tested is taken from an element's attribute. The list it is to be tested against comes from the invocation of the stylesheet, and is taken as a top-level <xsl:param> (to be provided on the command-line when I call xsltproc or a Saxon equivalent invocation). For example, the input value may be:

v0_01,v0_10,v0_99

while the attribute values will each look very much like one such value. (Whether a comma is used to separate values, or a space, is not important-- I chose a comma for now because I plan on passing the value via command-line switch to xsltproc, and using a space would require quoting the argument, and I'm lazy-enough to not want to type the extra two characters.)

What I am looking for is something akin to Perl's grep, wherein I can see if the value I currently have is contained in the list. It can be done with sub-string tests, but this would have to be clever so as not to get a false-positive (v0_01 should not match a string that contains v0_011). It seems that the only non-scalar data-type that XSL/XSLT supports is a node-set. I suppose it's possible to convert the list into a set of text nodes, but that seems like over-kill, even compared to making a sub-string test with extra boundaries-checking to prevent false matches.

like image 798
rjray Avatar asked Dec 10 '08 13:12

rjray


People also ask

How do you check if an element is in a list?

We can use the in-built python List method, count(), to check if the passed element exists in the List. If the passed element exists in the List, the count() method will show the number of times it occurs in the entire list. If it is a non-zero positive number, it means an element exists in the List.

How do you check if multiple elements are in a list?

Use the all() function to check if multiple values are in a list, e.g. if all(value in my_list for value in multiple_values): . The all() function will return True if all of the specified values are in the list and False otherwise.

Can we access the elements of a list?

There are various methods to access the elements of a list, but sometimes we may require to access element along with the index on which it is found. Let's see all the different way of accessing both index and value in a list.

How do you check if an element in a list is a string?

We can use Python in operator to check if a string is present in the list or not. There is also a not in operator to check if a string is not present in the list.


2 Answers

Actually, using XPath string functions is the right way to do it. All you have to make sure is that you test for the delimiters as well:

contains(concat(',' $list, ','), concat(',', $value, ','))

would return a Boolean value. Or you might use one of these:

substring-before(concat('|,' $list, ',|'), concat(',', $value, ','))

or

substring-after(concat('|,' $list, ',|'), concat(',', $value, ','))

If you get an empty string as the result, $value is not in the list.

EDIT:

@Dimitre's comment is correct: substring-before() (or substring-after()) would also return the empty string if the found string is the first (or the last) in the list. To avoid that, I added something at the start and the end of the list. Still contains() is the recommended way of doing this.

like image 179
Tomalak Avatar answered Sep 29 '22 17:09

Tomalak


In addition to the XPath 1.0 solution provided by Tomalak,

Using XPath 2.0 one can tokenize the list of values:

    exists(tokenize($list, ',')[. = $value])

evaluates to true() if and only if $value is contained in the list of values $list

like image 30
Dimitre Novatchev Avatar answered Sep 29 '22 17:09

Dimitre Novatchev