• « What a wonderful, wonderful medium we have in WeBlogs
    • |
    • Main
    • |
    • Bear with me on this.... read the following paragraph, memorize the general meaning, close your eyes, and... »
            • December 27, 2004

              XML and XSLT used to create the alphabetically sorted and individual/entity separated listing

            • For those interested I’ve posted the quick and dirty XSLT along with the XML source in which I used to create the new “Legends of the XSLT Community” listing with proper sorting and seperation of individuals and entitities. There are some obvious problems with this code. First, by using the “quick and dirty” sort method of:

              <xsl:sort select=”substring-after(., ’ ‘)”/>

              “G. Ken Holman” is sorted via “Ken” instead of “Holman” and “George Christian Bina” by Christian instead of “Bina”. I doubt this is going to cause any major rumblings in the community but obviously this is a problem if you were to use this code to do your own sorting.

              I also prefer to separate out the formatting, in this case HTML elements and CSS classes, in a separate XML file so that it’s easier to use the same code for other output formats using a “output-definition” file to define what the output elements should be. But as I mentioned this was quick and dirty code to get the new “Legends of the XSLT Community” properly listed and sorted. I’ll update the code-base once I have a chance later this afternoon.

              Until then, enjoy!

              The XSLT:

              <?xml version="1.0"?>
              <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
                <xsl:template match="/members">
                  <div class="right-side-head-title">
                    <h2>Legends of the XSLT Community</h2>
                  </div>
                  <div class="right-side-head-sub-title">Individuals</div>
                  <div class="legends-container">
                    <xsl:apply-templates select="member[@type = 'individual']">
                      <xsl:sort select="substring-after(., ' ')"/>
                    </xsl:apply-templates>
                  </div>
                  <div class="right-side-head-sub-title">Entitities</div>
                  <div class="legends-container">
                    <xsl:apply-templates select="member[@type = 'entity']">
                      <xsl:sort select="substring-after(., ' ')"/>
                    </xsl:apply-templates>
                  </div>
                </xsl:template>
                <xsl:template match="member">
                  <div class="legends">
                    <a href="{@href}">
                      <xsl:value-of select="."/>
                    </a>
                  </div>
                </xsl:template>
              </xsl:stylesheet>
              

              The XML:

              <?xml version="1.0" encoding="utf-8"?>
              <members>
                <member type="individual" href="http://www.jclark.com/">James Clark</member>
                <member type="individual" href="http://www.adambosworth.net/">Adam Bosworth</member>
                <member type="entity" href="http://www.microsoft.com/">Microsoft Corporation</member>
                <member type="individual" href="http://www.Saxonica.com">Michael Kay</member>
                <member type="entity" href="http://www.Saxonica.com">Saxonica, Ltd.</member>
                <member type="individual" href="http://www.JeniTennison.com">Jeni Tennison</member>
                <member type="individual" href="http://www.dpawson.co.uk">Dave Pawson</member>
                <member type="individual" href="http://www.dcarlisle.demon.co.uk/david/">David Carlisle</member>
                <member type="individual" href="http://www.xmlshoestring.com">Wendell Piez</member>
                <member type="individual" href="http://norman.walsh.name">Norman Walsh</member>
                <member type="individual" href="http://fxsl.sourceforge.net/">Dimitre Novatchev</member>
                <member type="individual" href="http://www.cranesoftwrights.com/">G. Ken Holman</member>
                <member type="individual" href="http://blog.tkachenko.com/">Oleg Tkachenko</member>
                <member type="individual" href="http://www.snee.com/bob/">Bob DuCharme</member>
                <member type="individual" href="http://uche.ogbuji.net/uche.ogbuji.net/">Uche Ogbuji</member>
                <member type="individual" href="http://skew.org/">Mike Brown</member>
                <member type="entity" href="http://www.exslt.org/">EXSLT.org</member>
                <member type="entity" href="http://www.fourthought.com/">Fourthought</member>
                <member type="entity" href="http://4suite.org/index.xhtml">4suite.org</member>
                <member type="entity" href="http://topxml.com/">TopXML.com</member>
                <member type="individual" href="">Johannes Döbler</member>
                <member type="individual" href="http://sync.ro/">George Christian Bina</member>
                <member type="individual" href="">Salvatore Mangano</member>
                <member type="individual" href="">Martin Rowlinson</member>
                <member type="individual" href="">B. Tommie Usdin</member>
              </members>
              

              The output:

              <?xml version="1.0" encoding="UTF-8"?>
              <div class="right-side-head-title">
                <h2>Legends of the XSLT Community</h2>
              </div>
              <div class="right-side-head-sub-title">Individuals</div>
              <div class="legends-container">
                <div class="legends">
                  <a href="http://www.adambosworth.net/">Adam Bosworth</a>
                </div>
                <div class="legends">
                  <a href="http://skew.org/">Mike Brown</a>
                </div>
                <div class="legends">
                  <a href="http://www.dcarlisle.demon.co.uk/david/">David Carlisle</a>
                </div>
                <div class="legends">
                  <a href="http://sync.ro/">George Christian Bina</a>
                </div>
                <div class="legends">
                  <a href="http://www.jclark.com/">James Clark</a>
                </div>
                <div class="legends">
                  <a href="">Johannes D&#195;&#182;bler</a>
                </div>
                <div class="legends">
                  <a href="http://www.snee.com/bob/">Bob DuCharme</a>
                </div>
                <div class="legends">
                  <a href="http://www.Saxonica.com">Michael Kay</a>
                </div>
                <div class="legends">
                  <a href="http://www.cranesoftwrights.com/">G. Ken Holman</a>
                </div>
                <div class="legends">
                  <a href="">Salvatore Mangano</a>
                </div>
                <div class="legends">
                  <a href="http://fxsl.sourceforge.net/">Dimitre Novatchev</a>
                </div>
                <div class="legends">
                  <a href="http://uche.ogbuji.net/uche.ogbuji.net/">Uche Ogbuji</a>
                </div>
                <div class="legends">
                  <a href="http://www.dpawson.co.uk">Dave Pawson</a>
                </div>
                <div class="legends">
                  <a href="http://www.xmlshoestring.com">Wendell Piez</a>
                </div>
                <div class="legends">
                  <a href="">Martin Rowlinson</a>
                </div>
                <div class="legends">
                  <a href="http://www.JeniTennison.com">Jeni Tennison</a>
                </div>
                <div class="legends">
                  <a href="http://blog.tkachenko.com/">Oleg Tkachenko</a>
                </div>
                <div class="legends">
                  <a href="">B. Tommie Usdin</a>
                </div>
                <div class="legends">
                  <a href="http://norman.walsh.name">Norman Walsh</a>
                </div>
              </div>
              <div class="right-side-head-sub-title">Entitities</div>
              <div class="legends-container">
                <div class="legends">
                  <a href="http://www.exslt.org/">EXSLT.org</a>
                </div>
                <div class="legends">
                  <a href="http://www.fourthought.com/">Fourthought</a>
                </div>
                <div class="legends">
                  <a href="http://4suite.org/index.xhtml">4suite.org</a>
                </div>
                <div class="legends">
                  <a href="http://topxml.com/">TopXML.com</a>
                </div>
                <div class="legends">
                  <a href="http://www.microsoft.com/">Microsoft Corporation</a>
                </div>
                <div class="legends">
                  <a href="http://www.Saxonica.com">Saxonica, Ltd.</a>
                </div>
              </div>
              
            • Posted by m.david : December 27, 2004 05:00 AM GMT

            Trackback Pings

            TrackBack URL for this entry:
            http://www.xsltblog.com/xslt-blog-mt/mt-tb.cgi/238

            Comments

              • Using FXSL one would write:

                <?xml version="1.0"?>
                <xsl:stylesheet version="2.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    xmlns:f="http://fxsl.sf.net/"
                    exclude-result-prefixes="f xs">
                
                  <xsl:import href="strSplit-to-Words.xsl"/>
                <!-- This transformation must be applied to:
                testSplitToWords4.xml
                -->
                
                  <xsl:output indent="yes" omit-xml-declaration="yes"/>
                
                  <xsl:template match="/">
                    <xsl:for-each select="for $v in /*/*[@type='individual'] return f:lastWord($v)">
                      <xsl:sort select="substring(.,1,1)"/>
                
                      <xsl:value-of select="concat(., '&#xA;')"/>
                    </xsl:for-each>
                  </xsl:template>
                
                  <xsl:function name="f:lastWord" as="xs:string*">
                    <xsl:param name="vTexts" as="xs:string*"/>
                
                    <xsl:variable name="vwordNodes" as="node()*">
                      <xsl:call-template name="str-split-to-words">
                        <xsl:with-param name="pStr" select="$vTexts"/>
                        <xsl:with-param name="pDelimiters"
                            select="' .&#10;&#13;'"/>
                      </xsl:call-template>
                    </xsl:variable>
                
                    <xsl:sequence select="$vwordNodes[last()]/text()"/>
                  </xsl:function>
                </xsl:stylesheet>
                

                When the above transformation is applied on your source xml document:

                <members>
                
                  <member type="individual" href="http://www.jclark.com/">James Clark</member>
                
                  <member type="individual" href="http://www.adambosworth.net/">Adam Bosworth</member>
                
                  <member type="entity" href="http://www.microsoft.com/">Microsoft Corporation</member>
                
                  <member type="individual" href="http://www.Saxonica.com">Michael Kay</member>
                
                  <member type="entity" href="http://www.Saxonica.com">Saxonica, Ltd.</member>
                
                  <member type="individual" href="http://www.JeniTennison.com">Jeni Tennison</member>
                
                  <member type="individual" href="http://www.dpawson.co.uk">Dave Pawson</member>
                
                  <member type="individual" href="http://www.dcarlisle.demon.co.uk/david/">David Carlisle</member>
                
                  <member type="individual" href="http://www.xmlshoestring.com">Wendell Piez</member>
                
                  <member type="individual" href="http://norman.walsh.name">Norman Walsh</member>
                
                  <member type="individual" href="http://fxsl.sourceforge.net/">Dimitre Novatchev</member>
                
                  <member type="individual" href="http://www.cranesoftwrights.com/">G. Ken Holman</member>
                
                  <member type="individual" href="http://blog.tkachenko.com/">Oleg Tkachenko</member>
                
                  <member type="individual" href="http://www.snee.com/bob/">Bob DuCharme</member>
                
                  <member type="individual" href="http://uche.ogbuji.net/uche.ogbuji.net/">Uche Ogbuji</member>
                
                  <member type="individual" href="http://skew.org/">Mike Brown</member>
                
                  <member type="entity" href="http://www.exslt.org/">EXSLT.org</member>
                
                  <member type="entity" href="http://www.fourthought.com/">Fourthought</member>
                
                  <member type="entity" href="http://4suite.org/index.xhtml">4suite.org</member>
                
                  <member type="entity" href="http://topxml.com/">TopXML.com</member>
                
                  <member type="individual" href="">Johannes Döbler</member>
                
                  <member type="individual" href="http://sync.ro/">George Christian Bina</member>
                
                  <member type="individual" href="">Salvatore Mangano</member>
                
                  <member type="individual" href="">Martin Rowlinson</member>
                
                  <member type="individual" href="">B. Tommie Usdin</member>
                
                </members>
                

                The wanted result is produced:

                Bosworth
                
                Brown
                
                Bina
                
                Clark
                
                Carlisle
                
                DuCharme
                
                Döbler
                
                Holman
                
                Kay
                
                Mangano
                
                Novatchev
                
                Ogbuji
                
                Pawson
                
                Piez
                
                Rowlinson
                
                Tennison
                
                Tkachenko
                
                Usdin
                
                Walsh
                

                Cheers,
                Dimitre

              • Posted by: Dimitre at December 27, 2004 01:05 PM
              • 1. Of course, in my code xsl:sort should be without a select attribute. Then one could use simply xsl:perform-sort

                2. Obviously there are problems in capturing and rendering the code — grey on black is not too-readable and only the start of the code was captured in the code block.

                Cheers,
                Dimitre

              • Posted by: Dimitre at December 27, 2004 02:04 PM
              • AWESOME! Actually, this was the exact reason why I held off from taking this process any further as I wanted to learn how to do it in FXSL and then showcase this code instead (my desire is to standardize everything on FXSL from this point forward. Anything I list as “Quick and Dirty” from this point forward basically means “this is the quick 30 second answer from my current knowledge base, now let me go figure out the right and proper way to do it using FXSL.”

                To be honest as I look back it seems about 90% of my hacks-from-the-past tend to have no rhyme-nor-reason as far as being built on any standard foundation, instead being hacked together real-fast to solve the problem at hand without any sort of reusable connotations. Well, I should qualify that the xameleon library is the exception to this rule but since I have rediscovered the FXSL library (and given the xameleon library is unreleased) I am completely reworking the entire xameleon project based on FXSL, the ultimate goal being standardization, something I honestly believe we should push for as a community, right along with EXSLT. To me it seems like these would be easy to accomplish given that the code base already exists for EVERY major platform and would get us about 90-95% of the way to XSLT 2.0 (and in the case of FXSL even beyond that of XSLT 2.0) leaving a very small percentage to be picked-up and supported by the processors vendors. Oleg’s comments from before really do seem to make a lot of sense, especially in the “not-quite-a-standard” interim between now and when XSLT 2.0 finally does become a W3C recommended standard.

                Actually, to chronicle my own efforts at converting my internal base of XSLT code as well as my personal open source XSLT projects to FXSL (which includes the xameleon project) I’ve started up resuablog.com which I don’t plan on making an official announcement to until the addition of fxsl.reusablog.com hits the DNS system more widely (I plan to go beyond just fxsl and focus on every aspect of my software development, blogging each and every process as I go under various project names and as such third tier names.) Still, if you read this comment you can see the beginnings of the project at http://www.reusablog.com.

                Thanks for the code Dimitre!

              • Posted by: M. David Peterson at December 27, 2004 03:05 PM

            Post a comment




            Remember Me?

            (you may use HTML tags for style)

          • © 2005 :: <XSLT:Blog/> (xsltblog.com) is a product of M. David Peterson and FunctionalX Consulting. See Licensing Info Below.
          • Except where otherwise noted, this sites content and source code is licensed under the Attribution License from Creative Commons.