XQuery不同节点的使用

时间:2017-03-27 17:33:39

标签: xml xquery basex

所以我想在distint-nodes子句中插入函数for(参见下面的内容)。我为此目的使用BaseX。

这是我的代码:

<autores>{
  for $a in doc("libros.xml")//libro
  return 
    <autor>
    <nombre>{
      for $b in $a/autor
      return concat($b/nombre,' ',$b/apellido)
    }
    </nombre>
    {
      for $c in doc("libros.xml")//libro
      where $c/autor = $a/autor
      return $c/titulo
    }
    </autor> 

  }
</autores>

我想在第一个中使用此函数,因此它只返回<autor/>元素的唯一实例:

for $b in distinct-nodes($a/autor)
      return concat($b/nombre,' ',$b/apellido)

但是我收到以下错误(B​​aseX查询信息):

  

错误:   停在G:/ Pruebas XML / XML / xqueryLibros.xq,6/31:   [XPST0017]未知函数:fn:distinct-nodes。

为什么这个功能存在时是未知的?我有什么遗失的吗?

编辑:我的目的是获取元素$a/autor的唯一实例,其中$a/autor/nombre$a/autor/apellidos文本值相同

<autores>
  <autor>
    <nombre>W. Stevens</nombre>
    <titulo>TCP/IP Ilustrado</titulo>
    <titulo>Programación Avanzada en el entorno Unix</titulo>
  </autor>
  <autor>
    <nombre>W. Stevens</nombre>
    <titulo>TCP/IP Ilustrado</titulo>
    <titulo>Programación Avanzada en el entorno Unix</titulo>
  </autor>
  <autor>
    <nombre>Serge Abiteboul Peter Buneman Dan Suciu</nombre>
    <titulo>Datos en la Web</titulo>
  </autor>
  <autor>
    <nombre/>
  </autor>
</autores>

2 个答案:

答案 0 :(得分:5)

没有标准的XQuery函数fn:distinct-nodes(...),XQuery只知道fn:distinct-values(...)

第三方XQuery函数库functx知道functx:dinstinct-nodes(...) function,它再次作为标准XQuery函数实现。该库可以是downloaded并作为大多数XQuery实现的模块导入,因为它只使用标准的XQuery函数。

如果所有<autor/>元素都包含作者姓名,请考虑应用fn:distinct-values(...),然后重新创建<autor/>元素。

出于性能原因,如果编译时间增加太多(库很大),则只提取所需的函数可能是合理的。另外请注意,某些功能具有更快的XQuery 3.0对应功能,充分利用了新的语言功能。

fn是默认的XQuery函数名称空间,funct是由函数库定义的名称空间。

答案 1 :(得分:2)

任何包含“/”运算符的路径表达式都会自动消除重复的节点,因此写functx:distinct-nodes($a/autor)完全是多余的,它将始终返回与$a/autor完全相同的结果。

但我怀疑你误解了functx:distinct-nodes()的作用。如果你有结构

<authors>
 <author>John Smith</author>
 <author>John Smith</author>
</authors>

然后authors/authorfunctx:distinct-nodes(authors/author)都将返回<author>个元素。它们被认为是不同的,因为它们是可区分的(例如,一个有兄弟姐妹,另一个没有)。如果你想将它们视为重复,那么你需要首先准确地定义重复的意思(也许你想要的定义是它们在fn意义上是深度相等的:深度相等的函数)然后你需要采用不同的方法。

后来:

在您对问题的编辑中,您已经说过两位作者对(非)不同的含义:“...其中$ a / autor / nombre和$ a / autor / apellidos文本值相同”

因此,最好将此视为分组问题:将$ a / autor / nombre和$ a / autor / apellidos相同的元素分组,然后从每个组中选择一个元素。

在XQuery 3.0中,使用FLWOR表达式的“group by”子句进行分组:

for $a in autor
group by $n := $a/nombre, $ap := $a/appellidos
return $a[1]

在XQuery 1.0中,它更笨拙,你通常会编写像

这样的东西
let $keys := distinct-values(autor/concat(nombre, '~', appellidos))
for $key in $keys
return /autor[concat(nombre, '~', appellidos) = $key][1]