0
votes

I have a collection of files describing magazines content

<magazine>
<issue.number>22</issue.number>
 <article>
<title>first article</title>
<subject>James</James>
</article>
<article>
<title>second article</title>
<subject>James</subject>
</article>
</magazine>

I want to output a list of articles in a format of <issue.number>, <title>.

So I created an XQuery:

for $x in /magazine
return concat($x/issue.number/text(),',',$x//title/text())

This results in an error, which I think is caused because the <issue.number> value is being returned twice. In eXist DB I get this:

The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: concat($atomizable-values as xdt:anyAtomicType?, ...) xs:string?. Expected cardinality: zero or one, got 2.

So if I can't use concat() what can I use?

1
Please have a look at the preview before posting, HTML elements need to be escaped as code to get printed. I also fixed to minor syntax errors (For and a missing variable name), please make sure to copy-paste code, not type it again to prevent such mistakes. - Jens Erat
Thanks for that Jens, I saw your edit, and visited your profile page but didn't see a message or 'thanks' facility. I appreciate it. - Jack

1 Answers

2
votes

The problem is that there are two articles in that magazine element, so you're passing two values as the third parameter of concat(...). Also, you don't need to use text() in here (and for most cases, shouldn't).

For once loop over the magazines, then again over the articles. It would be also fine to only loop over the articles, but then you'd have to use the parent-axis which I prefer to avoid.

for $magazine in $xml/magazine
for $article in $magazine/article
return concat($magazine/issue.number, ',', $article//title)

22,first article
22,second article


For concatenation over sequences of strings, have a look at string-join($sequence, $seperator). An example would be if you want all titles of one issue in a row.

for $magazine in $xml/magazine
return concat($magazine/issue.number, ': ', string-join($magazine//title, ', '))

which would return

22: first article, second article