There is a bug that remains, in the else if (xpathobj->type == XPATH_STRING) case.
As it is now, it simply passes the string value of the result into the output column's type-input function, regardless of the output column type.
If the output column type is xml, this will attempt to parse the string as xml. The result should simply be xml content consisting of a text node representing the string (as by XMLTEXT()). If it contains XML metacharacters, they should be escaped.
For a non-xml output column, the string should be used directly, as it is now.
# select * from xmltable('.' passing xmlelement(name a) columns a text path '"<foo/>"', b xml path '"<foo/>"'); a | b --------+-------- <foo/> | <foo/>