[xquery-talk] Generating an element sequence matching a template

Howard Katz howardk at fatdog.com
Tue Apr 25 15:13:21 PDT 2006


It actually gets a bit harder yet. If we now omit the first <e_1> in the
row-data:

let $headers := ( "e_1", "e_2", "e_3", "e_1", "e_4" )
let $row-data := ( <e_3>33</e_3>, <e_1>123</e_1>, <e_4>44</e_4> )

we end up with:

<e_1>123</e_1>, <e_2/>, <e_3>33</e_3>, <e_1/>, <e_4>44</e_4>

I'm not 100% sure about this, but I would think a more "correct" ordering
would be one that preserved the original order of $row-data as much as
possible, as in:

<e_1/>, <e_2/>, <e_3>33</e_3>, <e_1>123</e_1>, <e_4>44</e4>

However, if it's not possible to produce a solution that preserves the
ordering in this fashion, I'll need to mull whether I can live with that.
Since I don't have a better solution on hand, that might well have to be ok.

Howard

 > -----Original Message-----
 > From: Michael Kay [mailto:mhk at mhk.me.uk] 
 > Sent: April 25, 2006 1:50 PM
 > To: 'Howard Katz'; talk at xquery.com
 > Subject: RE: [xquery-talk] Generating an element sequence 
 > matching a template
 > 
 > Yes, this makes the problem harder. Something like
 > 
 > for $t at $pos in $template 
 > let $c := count($template[position() le $pos][. eq $t])
 > return element {$t} { string($row-data[local-name()=$t][$c]) }
 > 
 > Michael Kay
 > http://www.saxonica.com/
 > 
 > > -----Original Message-----
 > > From: Howard Katz [mailto:howardk at fatdog.com] 
 > > Sent: 25 April 2006 21:35
 > > To: 'Michael Kay'; talk at xquery.com
 > > Subject: RE: [xquery-talk] Generating an element sequence 
 > > matching a template
 > > 
 > > That does indeed work with the given example, but it fails in 
 > > a slightly more complex case, one that unfortunately I didn't 
 > > think to provide. I showed an example with duplicate entries 
 > > in the template; I should have shown one that also has 
 > > duplicates in the *data*, a not uncommon occurrence.
 > > 
 > > For example, this solution doesn't work if there are 
 > > duplicate <e_1> nodes in the data:
 > > 
 > > let $template := ( "e_1", "e_2", "e_3", "e_1", "e_4" ) let 
 > > $row-data := ( <e_1>11</e_1>, <e_3>33</e_3>, 
 > > <e_1>e_11-2</e_1>, <e_4>44</e_4> )
 > > 
 > > Saxon reports "A sequence of more than one item is not 
 > > allowed as the first argument of string()".
 > > 
 > > Any thoughts?
 > > 
 > > Howard
 > > 
 > >  > -----Original Message-----
 > >  > From: talk-bounces at xquery.com
 > >  > [mailto:talk-bounces at xquery.com] On Behalf Of Michael Kay  
 > > > Sent: April 25, 2006 11:55 AM  > To: 'Howard Katz'; 
 > > talk at xquery.com  > Subject: RE: [xquery-talk] Generating an 
 > > element sequence  > matching a template  >  > Isn't it simply:
 > >  >
 > >  > for $t in $template return
 > >  >   element {$t} { string($row-data[local-name()=$t]) }
 > >  >
 > >  > Michael Kay
 > >  > http://www.saxonica.com/
 > >  >
 > >  > > -----Original Message-----
 > >  > > From: talk-bounces at xquery.com
 > >  > > [mailto:talk-bounces at xquery.com] On Behalf Of Howard 
 > > Katz  > > Sent: 25 April 2006 19:39  > > To: talk at xquery.com  
 > > > > Subject: [xquery-talk] Generating an element sequence  > 
 > > > matching a template  > >  > >  > > Given a template of 
 > > element names, I want to be able to write  > > an XQuery 
 > > function that takes that template, as well as a  > > sequence 
 > > of element nodes, and returns a "filled-out" list of  > > 
 > > elements where the template supplies the final length of the  
 > > > > list and the names of empty elements to add to it if 
 > > they're  > > missing from the data. It's probably easier to 
 > > provide an  > > example than describe it.
 > >  > >
 > >  > > For example, given the data:
 > >  > >
 > >  > > let $template := ( "e_1", "e_2", "e_3", "e_1", "e_4" ) 
 > > let  > > $row-data := ( <e_1/>11</e_1>, <e_3>33</e_3>, 
 > > <e_4>44</e_4> )  > >  > > I want the "fill-row-data( 
 > > $template as xs:string+, $row-data  > > as element()+ )" 
 > > function to return this sequence:
 > >  > >
 > >  > > ( <e_1/>11</e_1>, <e_2/>, <e_3>33</e_3>, <e_1/>, 
 > > <e_4>44</e_4> )  > >  > > The initial $row-data will contain 
 > > some or all of the  > > elements named in the template, and 
 > > in the same order where  > > present. The number of nodes in 
 > > the final result will be the  > > same as the number of names 
 > > in the template. Where the  > > element sequence has nodes 
 > > corresponding to the template,  > > those nodes are left as 
 > > is. Where nodes that are named in the  > > template are 
 > > missing from the actual data, empty filler nodes  > > are 
 > > generated (eg <e_2/> and <e_1/>.
 > >  > >
 > >  > > The problem is motivated by a desire to produce an xhtml 
 > >  > > table where the list of <th> headers is fixed, but the 
 > > actual  > > data rows are sparse and heterogenous. I want to 
 > > be able to  > > generate homogenous rows so that the contents 
 > > of each row  > > exactly matches the given header. 
 > >  > >
 > >  > > Howard
 > >  > >
 > >  > > _______________________________________________
 > >  > > talk at xquery.com
 > >  > > http://xquery.com/mailman/listinfo/talk
 > >  >
 > >  > _______________________________________________
 > >  > talk at xquery.com
 > >  > http://xquery.com/mailman/listinfo/talk
 > >  > 
 > > 
 > 



More information about the talk mailing list