2
votes

I'm using XQuery to select a list of nodes from an XML according to some conditions. The result is a list of a couple of nodes, but I only want to return one (first or last) of them.

First I use XPath to select some elements, then I want to filter out any element that does not contain a value (ie. is empty). For that I am using the functx:if-not-empty function. What I get is a sequence of items and I only need one of them. This is my code so far:

declare function xf:createHeader($var as element(sgi:inputType))
    {
        <ns0:Header>
            <ns0:MSG_TYPE>MESSAGETYPE</ns0:MSG_TYPE>
            <ns0:MSG_NAMESPACE>{ fn:namespace-uri($var) }</ns0:MSG_NAMESPACE>            
            <ns0:UNIT>
            {   
                let $x := $var/DataArea/OrganisationalUnit[@type = "Responsible"]/PartnerID[@agencyID = "TT4"]
                for $y in $x 
                    where functx:if-not-empty($y)
                    return data($y)
            }
            </ns0:UNIT>           
        </ns0:Header>
};
1

1 Answers

1
votes

What you are looking for is a predicate. You can wrap the for statement in a predicate and ask for the first with [1] or the last with [fn:last()]

so it would look like

    <ns0:UNIT>
    {   
        let $x := $var/DataArea/OrganisationalUnit[@type = "Responsible"]/PartnerID[@agencyID = "TT4"]
        return
        (
            for $y in $x 
            where functx:if-not-empty($y)
            return data($y)
        )[fn:position() = (1,fn:last())]
    }
    </ns0:UNIT>