Xquery(XDMP-ARGTYPE错误)函数输入的预期类型与实际类型不同

时间:2016-06-25 21:48:21

标签: string xquery marklogic type-conversion untyped-variables

我尝试使用此功能从MarkLogic 8中的文本中删除停用词:

declare function rec:remove-stop-words($string, $stop_words)  {  
  (: This is a recursive function. :)  
  if(not(empty($stop_words))) then  
    rec:remove-stop-words(  
      replace($string, $stop_words[1], '', 'i'),  
      (: This passes along the stop words after 
         the one just evaluated. :)  
      $stop_words[position() > 1]  
    )  
  else normalize-space($string)  
};  

我在这里称之为

for $r in /rec:Record
return
  rec:remove-stop-words(data($r/rec:Abstract), $stop_words}

它给我以下错误

  

XDMP-ARGTYPE:(错误:XPTY0004)fn:replace((xs:untypedAtomic(" 章节 利用n ...")的不对称性,xs:untypedAtomic(" 书 ...")之间的相互关系," a",""," i") - arg1不是xs:string类型?

该函数需要string类型,但实际类型为untypedAtomic。我不知道该怎么做! 注意:((问题不在于功能,因为我已尝试将其用于其他文本并且效果很好))。

我通过以下方式将untypedAtomic转换为string来尝试代码:

return
  <info>{rec:remove-stop-words(data(xs:string($r/rec:Abstract)), $stop_words)}</info>

但是我收到了这个错误:

  

XDMP-ARGTYPE :(错误:XPTY0004)fn:replace((&#34; 章节 利用n ...的不对称性,&#34;,&#34; 书 ......&#34;),&#34; a&#34;,&#34;&#34;,&#34; i&#34;) - arg1不是类型xs:string

3 个答案:

答案 0 :(得分:3)

问题在于,当您迭代/rec:Record并传递$r/rec:Abstract作为输入时,至少有一条记录会返回多个rec:Abstractrec:remove-stop-words的函数签名允许一系列值作为$string的输入,但是您调用fn:replace的函数体只处理单个值的输入,因此它抛出一个参数异常(给定xs:string+并期待xs:string?)。

您可以在调用函数之前迭代rec:Abstract来处理序列:

for $r in /rec:Record
for $a in $r/rec:Abstract
return
rec:remove-stop-words($a, $stop_words)

如果使用更严格的函数签名,它可以帮助避免这样的问题,或者至少使它们更容易调试。例如,如果将函数定义为仅允许第一个参数的单个输入:

rec:remove-stop-words($string as xs:string, $stop_words as xs:string*)
...

$string传递一个序列时会抛出一个类似的异常,但调用堆栈会更高,这可能会使这些类型的错误更加明显。

答案 1 :(得分:1)

看起来您正在向它发送节点而不是字符串。试试$r/rec:Abstract/text()$r/rec:Abstract/string()

答案 2 :(得分:1)

尝试使用此代码 -

for $r in /rec:Record

return
rec:remove-stop-words(fn:string($r/rec:Abstract), $stop_words}