Search code examples
xmlxpathxquery

distinct-values: The required item type of the first operand of '/' is node(), but the supplied expression has item type xs:anyAtomicType


I have this XML file:

<collection>
    <journal name = "La Repubblica" issn = "1">
        <volume number = "1" date = "12/04/2022">
            <article doi = "AB23">
                <author orcid = "XY21">
                    <firstname>Marco</firstname>
                    <surname>Rossi</surname>
                    <affiliation>Affi</affiliation>
                </author>
                <author orcid = "XYZ">
                    <firstname>Simone</firstname>
                    <surname>Mambo</surname>
                </author>
                <title>Stop alle mascherine</title>
                <abstract>Da maggio si può dire basta alle mascherine</abstract>
                <keyword>COVID</keyword>
            </article>
            <article doi = "AB60">
                <author orcid = "XY21">
                    <firstname>Marco</firstname>
                    <surname>Rossi</surname>
                    <affiliation>Affi</affiliation>
                </author>
                <title>Un altro titolo</title>
                <abstract>Un altro abstract</abstract>
                <keyword>Titolo</keyword>
            </article>
        </volume>
    </journal>
</collection>

and this xQuery script:

<publications>
{
    for $au in distinct-values(doc("collection.xml")//author)
    return
    <author orcid = "{ $au/@orcid }">
       <firstname>{ $au/firstname/text() }</firstname>
    </author>
}
</publications>

Unfortunately this is giving me:

XPTY0019 The required item type of the first operand of '/' is node(), but the supplied expression {$ar} has item type xs:anyAtomicType

  • How can I fix?

Solution

  • Assuming XQuery 3.0 is supported I think you want

    <publications>
    {
        for $au in doc("collection.xml")//author
        group by $author := $au
        return
        <author orcid = "{ $au[1]/@orcid }">
           <firstname>{ $au[1]/firstname/text() }</firstname>
        </author>
    }
    </publications>
    

    Online sample.

    I don't know the XQuery processor of Oracle but the documentation you linked to in the comments links to XQuery 3.0 so based on that I would hope the above is supported.

    It is not quite clear to me, which distinct value/grouping key you are looking for in author, given that your input sample has two or three child elements for that element. You can of course use e.g. group by $first-name := $au/firstname, $last-name := $au/surname instead.

    If you don't have support for XQuery 3, you need to use e.g.

    <publications>
    {
        for $au in distinct-values(doc("collection.xml")//author)
        let $author := (doc("collection.xml)//author[. = $au])[1]
        return
        <author orcid = "{ $author/@orcid }">
           <firstname>{ $author/firstname/text() }</firstname>
        </author>
    }
    </publications>