Indeed if you convert the text string to codepoints and the codepoints back to a string the newlines are present. I’m not sure understand why they don’t show up otherwise.

It’s the HTML rendering that suppresses newlines. You can add them server-side…

  let $value := request:parameter($p)
  return <tr><td>{
    for $line in tokenize($value, char('\n'))
    return ($line, <br/>)
  }</td><td>
  
…or return the result inside a pre tag:

  <td><pre>{
    request:parameter($p)
  }</pre></td>