Search code examples
xmlxquerymarklogic

xQuery convert string to xhtml


My script builds a string that I need to output to xhtml, but xdmp:unquote() does not seem to like quoted attribute values specifically the quotes. I end up with the quote character entity in the output where that actual quote mark (") should be.

Here is the string:

let $title_opts :=  if ( "M.D." eq $acad_title )
                then
                    '<option selected="SELECTED" value="M.D.">M.D.</option><option value="D.O.">D.O.</option>'
                else if ( "D.O." eq $acad_title ) 
                then
                    '<option value="M.D.">M.D.</option><option selected="SELECTED" value="D.O.">D.O.</option>'
                else
                    '<option value="M.D.">M.D.</option><option value="D.O.">D.O.</option>'

and the output:

return <select name="title" id="title">
            { xdmp:unquote( $title_opts ) }
        </select>

The angle brackets come out fine with xdmp:unquote(), but the quotes do not. How do I get everything to display properly?


Solution

  • Don't construct XQuery elements as strings. If you need to return multiple top-level elements and cannot wrap them in another element, use sequences.

    let $title_opts :=  if ( "M.D." eq $acad_title )
                    then
                    (
                        <option selected="SELECTED" value="M.D.">M.D.</option>,
                        <option value="D.O.">D.O.</option>
                    )
                    else if ( "D.O." eq $acad_title ) 
                    then
                    (
                        <option value="M.D.">M.D.</option>,
                        <option selected="SELECTED" value="D.O.">D.O.</option>
                    )
                    else
                    (
                        <option value="M.D.">M.D.</option>,
                        <option value="D.O.">D.O.</option>
                    )
    

    Better use a switch-statement anyway:

    let $title_opts := switch ($acad_title) 
        case "M.D." return
            (
                <option selected="SELECTED" value="M.D.">M.D.</option>,
                <option value="D.O.">D.O.</option>
            )
        case "D.O." return
            (
                <option value="M.D.">M.D.</option>,
                <option selected="SELECTED" value="D.O.">D.O.</option>
            )   
        default return
            (
                <option value="M.D.">M.D.</option>,
                <option value="D.O.">D.O.</option>
            )
    

    Or if you use element constructors, only add the attribute as needed.

    let $title_opts :=
        (
            element { "option" } {
                if ( "M.D." eq $acad_title )
                then attribute { "selected" } {"selected" }
                else (),
                attribute { "value" } { "M.D." },
                "M.D."
            },
            element { "option" } {
                if ( "D.O." eq $acad_title )
                then attribute { "selected" } {"selected" }
                else (),
                attribute { "value" } { "D.O." },
                "D.O."
            }
        )