1
votes

I will give an example to better clarify myself.

Example:

<asdf>
    <parentnode id ="1">
           <childnode>
            ...
            </childnode>
            <childnode>
            ...
            </childnode>
    </parentnode>
    <parentnode id ="2">
            <childnode>
            ...
            </childnode>
            <childnode>
            ...
            </childnode>
            <childnode>
            ...
            </childnode>
    </parentnode>
    <parentnode id ="3">
            <childnode>
            ...
            </childnode>
    </parentnode>
</asdf>

I need to count all childnodes of all parentnodes and give back the minimum count of childnodes of the given parentnode with its id.

For this example the solution would be:

<parentnode id="3" amount="1"/>

I don't really know where to begin. Do I have to count distinct elements in a for loop or is this also possible with an Xpath expression ? I'm not sure if this is the right direction:

let $a := fn:doc('asdf.xml')/asdf/*
 return 
for $z in distinct-values($a/name() = childnode )
 order by count($z) ascending
 return $z)[1]
2

2 Answers

2
votes
  • Sort those parentnode elements by the count() of the childnode
  • From that sorted sequence, select the first, which is the one with the least amount of childnode elements
  • then construct an element using the computed element constructor using the name() of the $least-children element, copying any of it's attributes, and then creating the @amount attribute using a computed attribute constructor assigning it the value of the count() of it's childnode elements

.

let $least-children := 
  (for $parent in $a
   order by count($parent/childnode) ascending
   return $parent)[1]

return
  element {$least-children/name()} { 
    $least-children/@*, 
    attribute {"amount"} { count($least-children/childnode)} 
  }
1
votes

Another way to identify the minimum count is to use the min function:

let $parents := asdf/parentnode,
    $counts := $parents/count(childnode),
    $min := min($counts),
    $parent := $parents[index-of($counts, $min)]
return 
    <parentnode id="{$parent/@id}" amount="{$min}"/>