The "or" operator in XPath is written "or". The "|" operator forms the union of two node-sets. In some contexts "|" has the same effect as "or", for example
tests whether the union of child::b and child::c contains any elements, which is exactly the same as writing test="b or c". But this equivalence only applies when the operands are node-sets.
Note that you don't need to apply the string() function to the result of local-name() because the result of local-name() is already a string.
Do you actually want to ignore the namespace URI of the elements? Usually this is questionable practice. I would normally recommend writing
test="self::frame | self::repeatingFrame | self::field | self::text"
which differs from your code in that it requires the element to be in no-namespace.
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference