将fn:data应用于信息节点时的奇怪行为

时间:2019-01-02 13:34:42

标签: marklogic marklogic-9

当我在MarkLogic中运行以下xquery时:”

xquery version "1.0-ml";

let $envelope := <envelope xmlns="http://marklogic.com/entity-services"> 
                                <info>hello</info>
                             </envelope>

return fn:data($envelope/es:info)

我收到此错误:

[1.0-ml] XDMP-NONMIXEDCOMPLEXCONT:fn:data(hello)-节点具有复杂类型且未混合复杂内容

奇怪的是,当我将info-node重命名为info1时,代码按预期工作:

xquery version "1.0-ml";

let $envelope := <envelope xmlns="http://marklogic.com/entity-services">
                         <info1>hello</info1>
                     </envelope>

return fn:data($envelope/es:info1)

结果是:您好(按预期)

有人可以向我解释这种黑魔法吗?

3 个答案:

答案 0 :(得分:1)

我猜这是因为模式entity-type.xsd将元素定义为非混合元素:

<xs:complexType name="InfoType">
    <xs:sequence>
      <xs:element ref="es:title"/>
      <xs:element ref="es:version"/>
      <xs:element ref="es:base-uri" minOccurs="0"/>
      <xs:element ref="es:description" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

<xs:element name="info" type="es:InfoType"/>

如果元素具有mixed="true"属性,则可以包含混合内容。因为在这种情况下您无法更改架构,所以我尝试使用string()

declare namespace es = "http://marklogic.com/entity-services";

let $envelope := <envelope xmlns="http://marklogic.com/entity-services"> 
                    <info>
                      <title>hello</title>
                      <version>1.0</version>
                    </info>
                 </envelope>

return $envelope/es:info/string()

如果需要的话,这会给您hello1.0

您使用info1的示例有效,因为该元素未在架构中定义(因此将不是有效的xml)。

答案 1 :(得分:1)

由于fn:data()与架构有潜在的交互作用,请考虑使用fn:string()将元素的文本作为字符串获取。

答案 2 :(得分:0)

当使用fn:data()时,MarkLogic尝试从您的数据中检索类型化的值。 MarkLogic将为此目的寻找合适的模式。由于您正在使用实体服务名称空间,因此它将查找实体服务模式。此架构对info元素有一个特殊的定义(如Michael正确提到的那样),它与您使用它的方式不匹配。

使用fn:string()代替fn:data()通常更健壮,因为它会绕过数据类型检查。使用在entity-services模式中未定义的元素名称可以快速解决,现在可以使用,但是要保证将来也可以使用将很难。

就个人而言,我建议您按预期使用实体服务名称空间。如果您需要添加其他元素,则可以将它们放在带有或不带有伴随模式的其他命名空间中。或者,只需完全删除名称空间。

HTH!