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

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

Reply via email to