当我在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)
结果是:您好(按预期)
有人可以向我解释这种黑魔法吗?
答案 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!