Search code examples
xmlxsltxpathxqueryflwor

How to pipe one FLWOR into another?


Simple FLWOR to get all the data (from what was a spreadsheet):

for $foo  in db:open("foo")
return $foo//text()

gives this type of output:

...    
Smallville, XX 12345-1234
Bob 
(123) 456-7809
(123) 876-3468
Smallville, XX 12345-1234
Alice
Smallville, XX 12345-1234
Fred
(123) 654-5432
Smallville, XX 12345-1234
...

and another which returns non-numeric data:

for $foo  in db:open("foo")
return $foo//text()[not(matches(., '[0-9]'))]

Which seems to return only the names. On that assumption, looking to trigger closing tags on a <person> and opening a new <person>, like:

<person>
<name>a</name>
<data>123</data>
<data>345</data>
<data>123 main st</data>
</person>

<person>
...
</person>

Or something like that. Only really looking to seperate individuals on the assumption that there aren't numerals in their name, and then creating some sort of entity in XML.

Just so long as each time a "name" is found that triggers closing tags and then "starting" a new person. Not at all sure of the standard lingo here.


Solution

  • The following creates a temporary XML structure, then iterates through each of the name elements, creating a person with the name and it's following-sibling::data elements.

    let $temp := 
      <doc>{
        for $foo in db:open("foo")
        return
          if (matches($foo, "[0-9]")) 
          then <data>{$foo}</data>
          else <name>{$foo}</name>
      }</doc>
    
    for $name in $temp/name
    return
      <person>{
        $name,
        $name/following-sibling::data[preceding-sibling::name[1]= $name]
      }</person>