From: Marc v. G. <mar...@gm...> - 2015-03-24 22:42:21
|
Thank you too, I somehow managed to miss transform.xq. Have to take a good look at that as it seems to have ideas in common. The prezi is very hard to navigate on my ipad. Cheers, --Marc > On 24 mrt. 2015, at 22:57, Joe Wicentowski <jo...@gm...> wrote: > > Thanks very much for pointing me to this, Marc. I remember coming across this a few months ago and wanting to take a closer look. This provides a good reason to do so! I also wanted to look into John Snelson's transform.xq (project home https://github.com/jpcs/transform.xq and slides https://prezi.com/a2m05knqfmie/transformxq-a-transformation-library-for-xquery-30/). If you've looked at that before, do you have any comment on similarities or differences between origami and transform.xq? > > Thanks again, > Joe > >> On Tue, Mar 24, 2015 at 5:05 PM, Marc van Grootel <mar...@gm...> wrote: >> Hi Joe, >> >> Though I do not have a solution for your exact problem I did create a small xquery templating library that uses some techniques using higher order functions [1]. Alas it's currently BaseX specific but maybe the tutorial blog posts give you some ideas [2]. Currently the library has issues and I am going to pick it up again the next months. >> >> [1] https://github.com/xokomola/origami >> [2] http://xokomola.com/ >> >> --Marc >> >>> On 24 mrt. 2015, at 17:40, Joe Wicentowski <jo...@gm...> wrote: >>> >>> Hi all, >>> >>> I am transforming some TEI into HTML, and trying to fix some patterns that are legal in TEI but not in HTML, using XQuery. For example, in TEI it's legal to have a <list> inside a <p>, but in HTML, <p> cannot contain a <ul>. I've written a function that fixes instances of this, but now I've encountered a second case (<blockquote> is not allowed inside of <p>), and I am trying to think of a way to generalize the function, so that I can pass it a set of parameters for in-memory transformation. However, I can't think of a way to do this. >>> >>> Does anyone have suggestions? If not, I'll send this to xquery-talk, but I thought I'd give this a shot here first. >>> >>> Thanks, >>> Joe >>> >>> >>> Here's my current code: >>> -- >>> xquery version "3.0"; >>> >>> declare namespace xhtml = "http://www.w3.org/1999/xhtml"; >>> >>> (: pull lists from within paragraphs out, constructing new paragraphs around non-list nodes as needed >>> newly constructed 'interior' nodes are given a @class of "continued-from-before-list" :) >>> declare function local:fix-lists($node) { >>> if ($node/self::xhtml:p/xhtml:ul) then >>> let $nodes := $node/node() >>> let $lists := $node/xhtml:ul >>> (: iterate through lists by their position within the sequence of nodes :) >>> let $positions := $lists ! index-of($nodes, .) >>> for $position at $n in $positions >>> (: surround preceding and following nodes with <p> tags :) >>> let $before := >>> if ($position gt 1) then >>> <p xmlns="http://www.w3.org/1999/xhtml">{ >>> if ($n = 1) then () else attribute class {'continued-from-before-list'}, >>> $nodes[position() = ($positions[$n - 1] + 1 to $position - 1)] >>> }</p> >>> else >>> () >>> let $list := $lists[$n] >>> let $after := if ($n = count($lists) and $position lt count($nodes)) then >>> <p xmlns="http://www.w3.org/1999/xhtml">{ >>> attribute class {'continued-from-before-list'}, >>> $nodes[position() gt $position] >>> }</p> else () >>> return >>> ( $before, $list, $after ) >>> else >>> typeswitch ($node) >>> case text() return $node >>> default return element {QName(namespace-uri($node), $node/local-name())} { $node/@*, for $child in $node/node() return local:fix-lists($child) } >>> }; >>> >>> let $node := >>> <div xmlns="http://www.w3.org/1999/xhtml"> >>> <p>blah >>> <ul/> >>> blah >>> </p> >>> </div> >>> return >>> local:fix-lists($node) >>> -- >>> >>> this query returns the desired form: >>> >>> <div xmlns="http://www.w3.org/1999/xhtml"> >>> <p>blah</p> >>> <ul/> >>> <p class="continued-from-before-list">blah</p> >>> </div> >>> >>> What I'd like is to turn this into a more generalizable function, like: >>> >>> local:fix-html($node, $parameters) >>> >>> where node is the HTML node I'd like to transform, and $parameters is a map containing a filter for selecting matches and a function to transform: >>> >>> filter-a: html:p[html:ul] >>> transform-a: for each html:ul, split the html:p and thereby promote the html:ul as a following- and preceding-sibling of the two new html:p elements >>> >>> filter-b: html:p[html:blockquote] >>> transform-b: for each html:blockquote, split the html:p and thereby promote the html:blockquote as a following- and preceding-sibling of the two new html:p elements >>> >>> However, I can't think of how to do this. Perhaps via higher order functions? >>> >>> It seems XSLT makes this pretty trivial (see Michael Kay's suggestion at http://stackoverflow.com/questions/4779871/xslt-move-node-one-level-up), but is there a good way in XQuery? >>> >>> Thanks, >>> Joe >>> ------------------------------------------------------------------------------ >>> Dive into the World of Parallel Programming The Go Parallel Website, sponsored >>> by Intel and developed in partnership with Slashdot Media, is your hub for all >>> things parallel software development, from weekly thought leadership blogs to >>> news, videos, case studies, tutorials and more. Take a look and join the >>> conversation now. http://goparallel.sourceforge.net/ >>> _______________________________________________ >>> Exist-open mailing list >>> Exi...@li... >>> https://lists.sourceforge.net/lists/listinfo/exist-open > |