RE: [xsl] Common Element Solution (XSL 2.0)

Subject: RE: [xsl] Common Element Solution (XSL 2.0)
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 22 Mar 2005 22:26:56 -0000
My suggestion would be to replace this:

   <xsl:for-each-group select="table/column" group-by="@name">
>       <xsl:variable name="name" select="@name"/>
>       <xsl:if 
> test="count(/tables/table/column[@name=$name])=count(/tables/table)">
>         <columnName><xsl:value-of select="@name"/></columnName>
>       </xsl:if>
>     </xsl:for-each-group>

by this:

  <xsl:for-each-group select="table/column" group-by="@name">
    <xsl:if test="count(current-group())=count(/tables/table)">
        <columnName><xsl:value-of
select="current-grouping-key()"/></columnName>
    </xsl:if>
  </xsl:for-each-group>

You could also move count(/tables/table) outside the loop into a variable.

Note that the algorithm only works if a column name can appear in a table at
most once.

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

> -----Original Message-----
> From: JBryant@xxxxxxxxx [mailto:JBryant@xxxxxxxxx] 
> Sent: 22 March 2005 21:23
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Common Element Solution (XSL 2.0)
> 
> This is neither a question nor an answer to someone else's 
> question. I had 
> to solve a problem today (finding all the common columns in an XML 
> representation of a database), and it occurred to me that the 
> solution 
> might be useful for others. So, I'm posting for the sake of 
> future archive 
> searchers. For several years (since early 2000), I would 
> occasionally need 
> an XSL solution and would search the archives for solutions to my 
> problems. Now that I use XSL all a lot (was only occasional 
> before), I'm 
> trying to give back a bit as my understanding grows.
> 
> Of course, if anyone does have comments, I welcome input. I'm 
> sure I'll 
> never stop learning (at least I hope not).
> 
> Given this XML file:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <tables>
>   <table name="table1">
>     <column name="col1"/>
>     <column name="col2"/>
>     <column name="col3"/>
>     <column name="col4"/>
>   </table>
>   <table name="table2">
>     <column name="col1"/>
>     <column name="col2"/>
>     <column name="col5"/>
>     <column name="col6"/>
>   </table>
>   <table name="table3">
>     <column name="col1"/>
>     <column name="col2"/>
>     <column name="col7"/>
>     <column name="col8"/>
>   </table> 
> </tables>
> 
> Find the columns shared by all tables, by column name.
> 
> The solution (in XSL 2.0):
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet version="2.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> 
>   <xsl:template match="/">
>     <commonColumns>
>       <xsl:apply-templates/>
>     </commonColumns>
>   </xsl:template>
> 
>   <xsl:template match="tables">
>     <xsl:for-each-group select="table/column" group-by="@name">
>       <xsl:variable name="name" select="@name"/>
>       <xsl:if 
> test="count(/tables/table/column[@name=$name])=count(/tables/table)">
>         <columnName><xsl:value-of select="@name"/></columnName>
>       </xsl:if>
>     </xsl:for-each-group>
>   </xsl:template>
> 
> </xsl:stylesheet>
> 
> Produces the following output with Saxon 8:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <commonColumns>
>   <columnName>col1</columnName>
>   <columnName>col2</columnName>
> </commonColumns>
> 
> FWIW
> 
> Jay Bryant
> Bryant Communication Services
> (presently consulting at Synergistic Solution Technologies)

Current Thread