Andy, et al,
Thank you for your examples (and apologies - I naturally managed to copy/paste the wrong function into my initial email ).
Higher order functions are, sadly, a bit outside of my wheelhouse, so I'm unable to fully appreciate their power and utility. But! happily I could work from your examples and get something that I can almost wrap my head around! Thank you so much!
Here's the final working example for me, I think: ``` declare function local:pb( $result as xs:string, $node as node() ) { concat( $result, "/"[$result], name($node), $node/@* ! local:atty(.) => string-join("") ) };
declare function local:atty( $att as attribute() ) as xs:string* { "[@" || name($att) || "='" || data($att) || "']" };
distinct-values( $input//* ! fold-left(ancestor-or-self::*, '', local:pb(?, ?)) ) ``` Again, I really appreciate the guidance! Thanks and have a pleasant weekend, Best, Bridger
On Fri, Oct 16, 2020 at 1:01 PM Andy Bunce bunce.andy@gmail.com wrote:
If you really don't want the leading /
declare function local:pathbuild($result as xs:string,$this as node()){ concat( $result, '/'[$result], name($this), $this/@*! concat("[@" , name(.) , "='" , data(.), "']")=>string-join('') ) };
On Fri, 16 Oct 2020 at 17:48, Andy Bunce bunce.andy@gmail.com wrote:
Hi Bridger,
How about..
declare function local:pathbuild($result as xs:string,$this as node()){ concat( $result, "/" , name($this), $this/@*! concat("[@" , name(.) , "='" , data(.), "']")=>string-join('') ) };
innermost($input//*)!fold-left(ancestor-or-self::*,'',local:pathbuild#2)
/Andy
On Fri, 16 Oct 2020 at 16:29, Bridger Dyson-Smith bdysonsmith@gmail.com wrote:
Hi all -
I hope you don't mind a question about serializing distinct XPaths. I'm trying to generate some reports for documentation and the available built-in and library functions[1] aren't quite what I need.
The output I'm after is: test/aaa/bbb[@type="foo"] test/aaa/bbb[@type="foo"][@enc="bar"] test/aaa/bbb[@type="bzz"][@enc="bar"] test/aaa/bbb[@type="qux"][@enc="bar"][@key="yes"][@point="start"] test/aaa/bbb[@type="qux"][@enc="bar"][@key="yes"][@point="end"]
I have a couple of functions that are getting me close, but I can't quite manage the output strings, and multiple children are causing me trouble (entirely too much like real life). Any help or suggestions would be greatly appreciated. I've created a gist[2] with the following example:
Thanks very much for your time and trouble. Best, Bridger
xquery version "3.1"; declare variable $input := <test> <aaa> <bbb type="foo">bbb content</bbb> </aaa> <aaa> <bbb type="foo" enc="bar">bbb content</bbb> </aaa> <aaa> <bbb type="bzz" enc="bar">bbb content</bbb> <bbb type="qux" enc="bar" key="yes" point="start">bbb content</bbb> <bbb type="qux" enc="bar" key="yes" point="end">bbb content</bbb> </aaa> </test>; declare function local:elem( $nodes as node()* ) as xs:string* { for $node in $nodes return( string-join( if ($node/@*) then (string-join((name($node) || string-join(for $att in $node/@* return local:atty($att))), "/"), local:elem($node/child::*)) else if ($node/child::*) then (for $child in $node/child::* return local:elem($child), local:elem($node/child::*)) else (name($node) || "/" || local:elem($node/child::*)) ) ) }; declare function local:atty( $att as attribute() ) as xs:string* { "[@" || name($att) || "='" || data($att) || "']" }; local:e2($input (: this currently returns test/aaa/bbb[@type='foo']/ / /aaa/bbb[@type='foo'][@enc='bar']/ / /aaa/bbb[@type='bzz'][@enc='bar']/ /bbb[@type='qux'][@enc='bar'][@key='yes'][@point='start']/ /bbb[@type='qux'][@enc='bar'][@key='yes'][@point='end']/ / :)
[1] fn:path, and the related functions from functx (functx:distinct-element-paths, functx:path-to-node, and functx:path-to-node-with-pos). The functx functions are really close and awesome, but I need to incorporate attributes into my output. [2] https://gist.github.com/CanOfBees/8cfb435ac06986c9b0b0c215a786f4d7