joewiz
9/11/2016 - 3:17 PM

Trim repeated siblings in an XML document, with XQuery

Trim repeated siblings in an XML document, with XQuery

<foo>
    <bar>
        <usg type="register">col.</usg>
        <usg type="hint">inf.</usg>
    </bar>
    <zbr>
        <usg type="hint">inf.</usg>
    </zbr>
</foo>
xquery version "3.1";

declare function local:trim-repeated-siblings($nodes as node()*) {
    for $node in $nodes
    return
        typeswitch ($node)
            case element() return
                if (some $sibling in $node/preceding-sibling::node() satisfies deep-equal($node, $sibling)) then 
                    ()
                else
                    element { node-name($node) } { $node/@*, local:trim-repeated-siblings($node/node()) }
            default return $node
};

let $node := 
    <foo>
        <bar>
            <usg type="register">col.</usg>
            <usg type="hint">inf.</usg>
            <usg type="register">col.</usg>
        </bar>
        <zbr>
            <usg type="hint">inf.</usg>
        </zbr>
    </foo>
return
    local:trim-repeated-siblings($node)