Using various XQuery nodes

So, I want to insert a function distint-nodes

into a sentence for

(see below). I am using BaseX for this purpose.

This is my code:

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

      

I want to use this function in the first one, so it only returns a unique instance of the element to me <autor/>

:

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

      

But I am getting the following error (BaseX Query info):

Error: Stopped at G: / Pruebas XML / XML / xqueryLibros.xq, 6/31: [XPST0017] Unknown function: fn: individual nodes.

Why is this feature unknown when it exists? Is there something I am missing?

EDIT: My goal is to get a unique instance of an element $a/autor

where $a/autor/nombre

and the $a/autor/apellidos

text values ​​are the same

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

      

+3


source to share


2 answers


There is no standard XQuery function fn:distinct-nodes(...)

, XQuery only knows fn:distinct-values(...)

.

The third-party XQuery function library functx

knows a function that is again implemented as standard XQuery functions. The library can be loaded and imported as a module with most XQuery implementations since it only uses standard XQuery functions. functx:dinstinct-nodes(...)

If all elements <autor/>

contain the author's name, consider applying fn:distinct-values(...)

and then re-create the elements <autor/>

.



For performance reasons, it may only be wise to extract the required functions if the compilation time is too long (the library is quite large). Also keep in mind that some functions have much faster copies of XQuery 3.0 using new language features.

fn

is the XQuery default function namespace funct

, which is defined by the function library.

+4


source


Any path expression containing the "/" operator automatically removes duplicate nodes, so the entry is functx:distinct-nodes($a/autor)

completely redundant, it always returns exactly the same result as $a/autor

.

But I suspect you misunderstood what it does functx:distinct-nodes()

. If you have a structure

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

      

then both authors/author

and functx:distinct-nodes(authors/author)

return both elements <author>

. They are considered distinct because they are distinguishable (for example, one has prior siblings and the other does not). If you want to treat them as duplicates, then you need to first define exactly what you mean by duplicates (perhaps the definition you want is that they are deep in the sense of the fn: deep-equal function) and then you you need to take a different approach.

LATER:

In your edit of the question, you said that this means the two authors are (not) different: "... where the values ​​for $ a / autor / nombre and $ a / autor / apellidos are the same."



So it's best to think of it as a grouping problem: group the elements where $ a / autor / nombre and $ a / autor / apellidos are the same, then select one element from each group.

In XQuery 3.0, grouping is done using the group by clause from the FLWOR expression:

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

      

In XQuery 1.0 it is much more awkward, you usually write something like

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

      

+2


source







All Articles