【问题标题】:xQuery convert string to xhtmlxQuery 将字符串转换为 xhtml
【发布时间】:2012-07-05 19:04:26
【问题描述】:

我的脚本构建了一个字符串,我需要将其输出到xhtml,但xdmp:unquote() 似乎不喜欢带引号的属性值,特别是引号。我最终在输出中的实际引号 (") 应该是引号字符实体。

这是字符串:

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>'

和输出:

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

xdmp:unquote() 的尖括号很好,但引号没有。如何让所有内容正确显示?

【问题讨论】:

  • 您可以使用 xdmp:unquote($title_opts, (), "repair-full"),但这会导致额外的 xml-pi。您自己直接使用元素构造函数的解决方案要好得多。您可以通过将 if 从外部元素 select 移动到该元素内来进一步改进它,这样您只需要一个 select 元素,并且只在适当的地方应用 selected 属性。

标签: xml xquery marklogic


【解决方案1】:

不要将 XQuery 元素构造为字符串。如果您需要返回多个顶级元素并且无法将它们包装在另一个元素中,请使用序列。

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>
                )

无论如何最好使用switch-statement:

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>
        )

或者如果你使用元素构造函数,只根据需要添加属性。

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."
        }
    )

【讨论】:

  • 看来switch语句在xquery版本“1.0-ml”中是不可用的,所以我这里使用了第一个解决方案。比我拥有的要好得多。
【解决方案2】:

您似乎正在尝试为 xhtml 构建选项元素。虽然我喜欢提供的许多其他解决方案中的 XQuery,但我相信代码有太多硬编码。为什么不将生成选项 XHTML 元素的工作转移到辅助函数中呢?

declare function local:xhtml-options( $options as xs:string*, $selected as xs:string*) as element(option)* {

    for $option in $options
    return
        element option {
            if($option = $selected) then attribute selected {"SELECTED"} else (),
            attribute value {$option},
            text { $option }
        }

};


local:xhtml-options( ("M.D.", "D.0"), $acad_title )

【讨论】:

    【解决方案3】:

    好的,看来我必须将我的选项构建为选择元素,而不是字符串:

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

    返回 { $title_opts }

    【讨论】:

      【解决方案4】:

      如果您要完全生成每个案例,您可以使用较短的文字 xml 构造函数,因为所有 qnames 都是常量

      ...

      使用动态构造函数的建议是因为您可以更轻松地有条件地生成元素的一部分,从而减少重复代码。完全构建每个变体会破坏这些好处......产生相同的结果但使用最多的代码。

      imho dericksons 是最优雅的

      所有变体在功能上都是等效的,并且应该具有相似的性能

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 2020-08-06
        • 2019-10-10
        • 2019-01-05
        • 2015-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多