The reason I asked was: although XQuery looks more procedural than XSLT, it’s 
still basically a functional and declarative language, and thinking about 
incrementing or decrementing variables is probably the wrong way to think about 
solving your problem in XQuery. 
Variables bind names to values over a particular scope, and they aren’t 
updatable variables that you can increment or decrement. 

If what you want in English is roughly:
  For person element where numerical = true , group by the preceding-sibling 
where numerical = false 

That maps fairly simply into XQuery syntax: 

declare variable $XML := <xml>
 <person id="1" x="0" numerical="false">people</person>
 <person id="2" x="0" numerical="false">joe</person>
 <person id="3" x="0" numerical="true">phone1</person>
 <person id="4" x="0" numerical="true">phone2</person>
 <person id="5" x="0" numerical="true">phone3</person>
 <person id="6" x="0" numerical="false">sue</person>
 <person id="7" x="0" numerical="true">cell4</person>
 <person id="8" x="0" numerical="true">home5</person>
 <person id="9" x="0" numerical="false">alice</person>
 <person id="10" x="0" numerical="true">atrib6</person>
 <person id="11" x="0" numerical="true">x7</person>
 <person id="12" x="0" numerical="true">y9</person>
 <person id="13" x="0" numerical="true">z10</person>
</xml> ;

for $P in $XML/person
where $P[@numerical="true"]
let $PREV := $P/preceding-sibling::person[@numerical="false"][1]
group by $PREV
return <person name="{$PREV}" >  { $P } </person>

Yields:


<person name="joe">
  <person id="3" x="0" numerical="true">phone1</person>
  <person id="4" x="0" numerical="true">phone2</person>
  <person id="5" x="0" numerical="true">phone3</person>
</person>
<person name="sue">
  <person id="7" x="0" numerical="true">cell4</person>
  <person id="8" x="0" numerical="true">home5</person>
</person>
<person name="alice">
  <person id="10" x="0" numerical="true">atrib6</person>
  <person id="11" x="0" numerical="true">x7</person>
  <person id="12" x="0" numerical="true">y9</person>
  <person id="13" x="0" numerical="true">z10</person>
</person>

Once the grouping is working, you can work on tweaking the output format to 
exactly what you want. I tried to work towards something like what I THOUGHT 
you might want. 
I had a bit of trouble understanding that $PREV in the return expression is an 
atomic string value and not a node, and that the other variables in return 
expression are multiple valued ( thus the ‘[1]’s ), but I ended up with this:


<people> {
for $P in $XML/person
where $P[@numerical="true"]
let $PREV := $P/preceding-sibling::person[@numerical="false"][1]
let $X := count($P[1]/preceding-sibling::person[@numerical="false"])
group by $PREV
return <person name="{$PREV}"  
x="{$X[1] - 1 }"
id="{$P[1]/preceding-sibling::person[@numerical="false"][1]/@id}" 
>  { for $I in $P return <number>{$I/@id, attribute x {$X[1]-1}, 
> string($I)}</number> }  </person>
} </people>

Which yields:

<people>
  <person name="joe" x="1" id="2">
    <number id="3" x="1">phone1</number>
    <number id="4" x="1">phone2</number>
    <number id="5" x="1">phone3</number>
  </person>
  <person name="sue" x="2" id="6">
    <number id="7" x="2">cell4</number>
    <number id="8" x="2">home5</number>
  </person>
  <person name="alice" x="3" id="9">
    <number id="10" x="3">atrib6</number>
    <number id="11" x="3">x7</number>
    <number id="12" x="3">y9</number>
    <number id="13" x="3">z10</number>
  </person>
</people>


Also more functional to think of use count or position expressions instead of 
incrementing or decrementing variables. 

I’m hitting the Walmsley book myself now to try to understand those issues with 
group by / return that were puzzling to me. 


— Steve M. 


> On Feb 19, 2020, at 8:28 PM, thufir <hawat.thu...@gmail.com> wrote:
> 
> Hi Steve,
> 
> yes, it certainly does.  At this point, I'd settle for adding an attribute 
> like "recordID", but that's exactly it.  I'll take a closer look at "group 
> by" a bit later, thanks for the pointer.  See also:
> 
> https://stackoverflow.com/q/60237739/262852
> 
> 
> thanks,
> 
> Thufir
> 
> On 2020-02-19 1:05 p.m., Majewski, Steven Dennis (sdm7g) wrote:
>>> On Feb 19, 2020, at 10:01 AM, thufir <hawat.thu...@gmail.com 
>>> <mailto:hawat.thu...@gmail.com>> wrote:
>>> 
>>> where I'm trying to use attributes because I'm not sure how to 
>>> conditionally nest tags.  But, this is interesting.  Not quite sure on 
>>> syntax to set and then conditionally increment $x, however.
>> Does “conditionally nest tags” mean that you want to make the 
>> person[@numerical=“true”] elements children of the immediately previous 
>> person[@numerical=“false”] elements ?
>> If that is the case you can use “group by”
>> — Steve M.

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to