|
xquery version "3.1"; |
|
|
|
declare variable $depth := 3; |
|
declare variable $xml := |
|
document { |
|
<div xml:id="d1"> |
|
<p>First <hi>section</hi> para 1</p> |
|
<p>First <hi>section</hi> <hi>para</hi> 2</p> |
|
<div xml:id="d2"> |
|
<p>First para in <hi>d2</hi></p> |
|
<p>Second para in <hi>d2</hi></p> |
|
<div xml:id="d7"> |
|
<p>First <hi>para</hi> in d7</p> |
|
<p>Second <hi>para</hi> in <hi>d7</hi></p> |
|
<!-- below div should be included in d7 output --> |
|
<div xml:id="d10"/> |
|
</div> |
|
</div> |
|
<div xml:id="d3"> |
|
<p>Third section</p> |
|
<div xml:id="d4"/> |
|
<div xml:id="d5"/> |
|
</div> |
|
<div xml:id="d6"> |
|
<p>Third <hi>section</hi> para 1</p> |
|
<p>Third <hi>section</hi> <hi>para</hi> 2</p> |
|
<div xml:id="d9"/> |
|
</div> |
|
<div xml:id="d8"/> |
|
</div> |
|
} |
|
; |
|
|
|
declare function local:filler($div) { |
|
if ($div/div and count(($div/div[1])/preceding-sibling::*//*) < 2) then |
|
$div/div[1] |
|
else |
|
() |
|
}; |
|
|
|
declare function local:needs-fill($div) { |
|
exists(local:filler($div)) |
|
}; |
|
|
|
declare function local:fill($div) { |
|
if ($div/div and count($div/ancestor-or-self::div) < $depth) then |
|
let $filler := local:filler($div) |
|
return |
|
if ($filler) then |
|
element { node-name($div) } { |
|
$div/@*, |
|
$filler/preceding-sibling::node(), |
|
$filler |
|
} |
|
else |
|
element { node-name($div) } { |
|
$div/@*, |
|
$div/div[1]/preceding-sibling::* |
|
} |
|
else |
|
$div |
|
}; |
|
|
|
declare function local:next-page($div) { |
|
let $filled := local:filler($div) |
|
return |
|
if ($filled) then |
|
$filled/following::div[1] |
|
else |
|
($div/descendant::div[count(ancestor-or-self::div) <= $depth], |
|
$div/following::div[count(ancestor-or-self::div) <= $depth])[1] |
|
}; |
|
|
|
declare function local:previous-page($div) { |
|
let $previous := $div/preceding::div[count(ancestor-or-self::div) <= $depth][1] |
|
let $parent := $div/ancestor::div[1] |
|
let $previous := if ($previous << $parent) then $parent else $previous |
|
return |
|
if ($previous) then |
|
let $parent := $previous/ancestor::div[1] |
|
return |
|
if (local:filler($parent) is $previous) then |
|
$parent |
|
else |
|
$previous |
|
else |
|
$div/ancestor::div[1] |
|
}; |
|
|
|
( |
|
local:fill(id('d1', $xml)), |
|
local:fill(local:next-page(id('d1', $xml))), (: d2 :) |
|
local:fill(local:next-page(id('d2', $xml))), (: d7 :) |
|
local:fill(local:next-page(id('d7', $xml))), (: d5 :) |
|
local:fill(local:next-page(id('d3', $xml))), (: d5 :) |
|
local:fill(local:next-page(id('d5', $xml))), (: d6 :) |
|
local:fill(local:next-page(id('d6', $xml))), (: d9 :) |
|
local:fill(local:next-page(id('d9', $xml))), (: d8 :) |
|
local:fill(local:previous-page(id('d8', $xml))), |
|
local:fill(local:previous-page(id('d9', $xml))), |
|
local:fill(local:previous-page(id('d6', $xml))), |
|
local:fill(local:previous-page(id('d5', $xml))), |
|
local:fill(local:previous-page(id('d3', $xml))), |
|
local:fill(local:previous-page(id('d7', $xml))), |
|
local:fill(local:previous-page(id('d2', $xml))) |
|
) |