[xquery-talk] moving an element from last child to next sibling

David Sewell dsewell at virginia.edu
Tue Oct 23 07:02:06 PDT 2012


There are at least a couple of different approaches to this via the typeswitch 
strategy, but I think the simplest would be:

1. In your function for closer, recurse over the child nodes as usual (which I 
assume will output a <closer> element, or whatever you transform it to), then 
process your postscript children:

    for $ps in $node/tei:postscript
    return <postscript>{$ps/@*, eccoparse:recurse($ps)}</postscript>

2. Extend your postscript function so it returns null if the postscript is a 
child of <closer>:

    declare function eccoparse:postscript($node as element(tei:postscript)) as
    element()*
    {
      if ($node/parent::tei:closer) then ()
      else <postscript>{$node/@*}{eccoparse:recurse($node)}</postscript>
    }

Speaking as someone who wrote a lot of pseudo-templates in XQuery before 
MarkLogic added an XSLT 2.0 parser to their product, this is one area where XSLT 
is a lot more pleasant to use, if that's a possibility.

David

On Tue, 23 Oct 2012, Martin Mueller wrote:

> I have used the xquery typeswitch function to transform elements from a TEI
> file, but I am stymied by a task involving the following fragment:
>
>    <closer>
>               <signed>Your ever affectionate WOODVILLE.</signed>
>               <postscript>
>                  <p>P.S. You have a house, within a mile of York; where we
> have spent many happy days—<q rend="inline">"Days of ease, and nights of
> pleasure."</q> Who knows but we may there recover our juve‑nile tastes and
> passions! impossible! As well when advanced in life, might we hope to
> reco‑ver our youth, <hi>in those fields where we once were young.</hi>—But
> is that house untenanted? Will you be our host? Or have you lett, or lent
> it?</p>
>               </postscript>
>            </closer>
>
> I want to move the <postscript> element from its position as the last child
> of <closer> into the position of right sibling of <closer> so that the
> desire output would look like this:
>
> <closer>
>           <signed>Your ever affectionate WOODVILLE.</signed>
>
> </closer>
> <postscript>
>                  <p>P.S. You have a house, within a mile of York; where we
> have spent many happy days—<q rend="inline">"Days of ease, and nights of
> pleasure."</q> Who knows but we may there recover our juve‑nile tastes and
> passions! impossible! As well when advanced in life, might we hope to
> reco‑ver our youth, <hi>in those fields where we once were young.</hi>—But
> is that house untenanted? Will you be our host? Or have you lett, or lent
> it?</p>
> </postscript>
>
>
> How do I do this? In a typeswitch function the different tasks relating to
> elements are carried out by subsidiary function. Here is the postscript
> function that simply passes through the element:
>
> declare function eccoparse:postscript($node as element(tei:postscript)) as
> element()
> {
> <postscript>{$node/@*}{eccoparse:recurse($node)}</postscript>
> };
>
>
>
> I know how to various things that would change the postscript element but
> leave it in its current place. But how do I put it in another place without
> changing anything in it?  Is this a task that should be done at the level of
> the parent element?
>
>
>
> I'll be grateful for any advice.
>
>
>
>
>
> Martin Mueller
>
> Professor emeritus of English and Classics
>
> Northwestern University
>
>
>
>
>

-- 
David Sewell, Editorial and Technical Manager
ROTUNDA, The University of Virginia Press
PO Box 400314, Charlottesville, VA 22904-4314 USA
Email: dsewell at virginia.edu   Tel: +1 434 924 9973
Web: http://rotunda.upress.virginia.edu/


More information about the talk mailing list