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

Michael Kay mhk at mhk.me.uk
Wed Apr 26 00:01:49 PDT 2006


I think you're looking for (1) a definition of the problem, (2) an
algorithm, and only then (3) an expression of that algorithm in XQuery...

Michael Kay
http://www.saxonica.com/


> -----Original Message-----
> From: Howard Katz [mailto:howardk at fatdog.com] 
> Sent: 25 April 2006 22:13
> To: 'Michael Kay'; talk at xquery.com
> Subject: RE: [xquery-talk] Generating an element sequence 
> matching a template
> 
> 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