A working example to clarify my request: \startluacode -- splits the attribute class using spaces as classes' separator -- returns an array of strings function xml.functions.classes(classAttr) local classes = {} if classAttr then for c in string.gmatch(classAttr, "%S+") do if (string.len(c) > 0) then classes[c] = true end end end return classes end function xml.expressions.hasClass(classAttr, className) if classAttr and className then return xml.functions.classes(classAttr)[className] ~= nil end return false end \stopluacode \startbuffer[test] <text> <p>Generic paragraph (no class).</p> <p class="myClass1">Emphasized paragraph (<tt>class="myClass1"</tt>).</p> <p class="otherClass myClass1">Another emphasized paragraph (but <tt>myClass1</tt> is not the only class specified). </p> <p class="myClass12">Another not emphasized paragraph (<tt>class="myClass12"</tt>) showing why <br/> <tt>p[hasClass(@class, "myClass1")]</tt><br/> is better than <br/> <tt>p[@class="myClass1"]</tt><br/> or <br/> <tt>p[contains(@class, "myClass1")]</tt>. </p> <p><tt>p[hasClass("myClass1")]</tt> would be better since it's obvious that the classes are specified in the <tt>class</tt> attribute, but this means that the lua expression needs to access the current selected element (<tt>ll</tt>?). </p> </text> \stopbuffer \startxmlsetups xml:somesetups \xmlsetsetup{#1}{text}{xml:text} \xmlsetsetup{#1}{p}{xml:p} \xmlsetsetup{#1}{p[hasClass(@class, 'myClass1')]}{xml:p:myClass1} \xmlsetsetup{#1}{tt}{xml:tt} \xmlsetsetup{#1}{br}{xml:br} \stopxmlsetups \xmlregistersetup{xml:somesetups} \startxmlsetups xml:text \xmlflush{#1} \stopxmlsetups \startxmlsetups xml:p \xmlflush{#1}\par\blank[line] \stopxmlsetups \startxmlsetups xml:p:myClass1 {\em\xmlflush{#1}}\par\blank[line] \stopxmlsetups \startxmlsetups xml:br \\ \stopxmlsetups \startxmlsetups xml:tt \dontleavehmode{\tt\xmlflush{#1}} \stopxmlsetups \starttext \xmlprocessbuffer{main}{test}{} \stoptext Thanks in advance for any help, Massi