Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

James Robertson http://www.r0bertson.co.uk

« Newer Snippets
Older Snippets »
Showing 21-28 of 28 total

Using the XSLT sum function

This XML and XSLT code is an example of storing and displaying a car mileage log. Notably the XSLT sum() function displays the total no of miles.


file: car_log.xsl
   1  
   2  <?xml version="1.0"?>
   3  
   4      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   5        
   6      <xsl:template match="car_log">
   7        <div>      
   8          <p>Total miles this month: <xsl:value-of select="sum(records/entry/miles)" /></p>
   9          <xsl:apply-templates select="records"/>
  10        </div>
  11      </xsl:template>
  12      
  13      <xsl:template match="car_log/records/entry"><xsl:variable name="pos" select="position()"/>
  14      <div class="record">
  15        <dl>
  16          <dt><label for="trip"><xsl:value-of select="@title"/>trip</label></dt>
  17          <dd>
  18            <input type="text" id="trip{$pos}" name="trip{$pos}" value="{trip}" size="{@size}" />
  19          </dd>
  20            
  21          <dt><label for="miles"><xsl:value-of select="@title"/>miles</label></dt>
  22          <dd>
  23            <input type="text" id="miles{$pos}" name="miles{$pos}" value="{miles}" size="2" />
  24          </dd>
  25            
  26          <dt><label for="description"><xsl:value-of select="@title"/>description</label></dt>
  27          <dd>
  28            <input type="text" id="description{$pos}" name="description{$pos}" value="{description}"  />
  29          </dd>        
  30        </dl>
  31      </div>
  32      </xsl:template>
  33      </xsl:stylesheet>

file: car_log.xml
   1  
   2  <car_log>
   3    <summary>
   4      <project>car_log</project>
   5    </summary>
   6    <records>
   7      <entry id='17962'><date>Wed Dec 12 20:00:33 +0000 2007</date><trip>trip to the supermarket</trip><miles>11.8</miles><description>my first trip with the GPS installed</description></entry>
   8      <entry id='18024'><date>Fri Dec 14 11:45:09 +0000 2007</date><trip>driving around the park</trip><miles>26.1</miles><description/></entry>
   9      <entry id='18173'><date>Thu Dec 20 01:21:27 +0000 2007</date><trip>trip to the supermarket</trip><miles> 8.5</miles><description/></entry>
  10      <entry id='18174'><date>Thu Dec 20 01:34:26 +0000 2007</date><trip>visiting parents</trip><miles>12.7</miles><description/>
  11      </entry>
  12    </records>
  13  </car_log>

output
   1  
   2  Total miles this month: 59.1
   3  ...

Zebra stripes on rows using XSLT

Using XSL every 2nd row will contain the class named 'stripe'.
   1  
   2    <xsl:element name="li">
   3          <xsl:if test="(position() mod 2) != 1">
   4            <xsl:attribute name="class"><xsl:text>stripe</xsl:text></xsl:attribute>
   5  	</xsl:if>
   6    </xsl:element>

Pretty Print XML using Ruby

This code makes the XML output look pretty. I tried using the documentation from the REXML website to apply the method example doc.write($stdout,0), but I gave up, and instead wrote my own XML pretty-print method.

   1  
   2  require 'rexml/document'
   3  include REXML
   4  
   5    def pretty_print(parent_node, itab)
   6      buffer = ''
   7  
   8      parent_node.elements.each do |node|
   9  
  10        buffer += ' ' * itab + "<#{node.name}#{get_att_list(node)}"
  11    
  12        if node.to_a.length > 0
  13          buffer += ">"
  14          if node.text.nil?
  15            buffer += "\n"
  16            buffer += pretty_print(node,itab+2) 
  17            buffer += ' ' * itab + "</#{node.name}>\n"
  18          else
  19            node_text = node.text.strip
  20            if node_text != ''
  21              buffer += node_text 
  22              buffer += "</#{node.name}>\n"        
  23            else
  24              buffer += "\n" + pretty_print(node,itab+2) 
  25              buffer += ' ' * itab + "</#{node.name}>\n"        
  26            end
  27          end
  28        else
  29          buffer += "/>\n"
  30        end
  31        
  32      end
  33      buffer
  34    end
  35  
  36    def get_att_list(node)
  37      att_list = ''
  38      node.attributes.each { |attribute, val| att_list += " #{attribute}='#{val}'" }
  39      att_list
  40    end
  41    
  42    def pretty_xml(doc)
  43      buffer = ''
  44      xml_declaration = doc.to_s.match('<\?.*\?>').to_s
  45      buffer += "#{xml_declaration}\n" if not xml_declaration.nil?
  46      xml_doctype = doc.to_s.match('<\!.*\">').to_s
  47      buffer += "#{xml_doctype}\n" if not xml_doctype.nil?
  48      buffer += "<#{doc.root.name}#{get_att_list(doc.root)}"
  49      if doc.root.to_a.length > 0
  50        buffer +=">\n#{pretty_print(doc.root,2)}</#{doc.root.name}>"
  51      else
  52        buffer += "/>\n"
  53      end
  54    end
  55  
  56  xml_data = "<hi id='124'><yo><a id='1'/><b/><c/></yo><sushi><love>Ruby</love></sushi></hi>"
  57  doc = Document.new(xml_data)
  58  pretty_xml(doc)
  59  

output
   1  
   2  <hi id='124'>
   3    <yo>
   4      <a id='1'/>
   5      <b/>
   6      <c/>
   7    </yo>
   8    <sushi>
   9      <love>Ruby</love>
  10    </sushi>
  11  </hi>


*Update 7-Jan-08 1:51AM *
Although I haven't tried running the following XSL code, this might actually have been a better solution to my problem. source: http://www.printk.net/~bds/indent.html

*Pretty Print XML using XSLT*
   1  
   2  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   3    <xsl:output method="xml" encoding="ISO-8859-1"/>
   4    <xsl:param name="indent-increment" select="'   '"/>
   5    
   6    <xsl:template name="newline">
   7      <xsl:text disable-output-escaping="yes">
   8  </xsl:text>
   9    </xsl:template>
  10    
  11    <xsl:template match="comment() | processing-instruction()">
  12      <xsl:param name="indent" select="''"/>
  13      <xsl:call-template name="newline"/>    
  14      <xsl:value-of select="$indent"/>
  15      <xsl:copy />
  16    </xsl:template>
  17    
  18    <xsl:template match="text()">
  19      <xsl:param name="indent" select="''"/>
  20      <xsl:call-template name="newline"/>    
  21      <xsl:value-of select="$indent"/>
  22      <xsl:value-of select="normalize-space(.)"/>
  23    </xsl:template>
  24      
  25    <xsl:template match="text()[normalize-space(.)='']"/>
  26    
  27    <xsl:template match="*">
  28      <xsl:param name="indent" select="''"/>
  29      <xsl:call-template name="newline"/>    
  30      <xsl:value-of select="$indent"/>
  31        <xsl:choose>
  32         <xsl:when test="count(child::*) > 0">
  33          <xsl:copy>
  34           <xsl:copy-of select="@*"/>
  35           <xsl:apply-templates select="*|text()">
  36             <xsl:with-param name="indent" select="concat ($indent, $indent-increment)"/>
  37           </xsl:apply-templates>
  38           <xsl:call-template name="newline"/>
  39           <xsl:value-of select="$indent"/>
  40          </xsl:copy>
  41         </xsl:when>       
  42         <xsl:otherwise>
  43          <xsl:copy-of select="."/>
  44         </xsl:otherwise>
  45       </xsl:choose>
  46    </xsl:template>    
  47  </xsl:stylesheet>

Generate an XSL file for a simple XML file

Using Ruby and XSLT this code creates an xsl file for a corresponding xml file. Note: It only reproduces xml elements in the xsl file, not element attributes.
   1  
   2  #!/usr/bin/ruby
   3  # file: xml2xsl.rb
   4  
   5  # author: jrobertson
   6  # created: 31-Dec-07
   7  # description: 
   8  #   Converts an xml file into another xml file in 'xml2xsl' format.
   9  #   This new xml file can then be transformed with the stylesheet 
  10  #   xml2xsl.xsl into a multi-purpose xsl file template for the original 
  11  #   xml file.
  12  
  13   
  14  require 'rexml/document'
  15  include REXML
  16  
  17  class PreXml2Xsl
  18  
  19    def pre_xml2xsl(doc)
  20      puts '<xsl>'
  21      puts "  <template name='" + doc.root.name + "'>"
  22      build_xml(doc.root)
  23      puts '    </template>'
  24      puts '</xsl>'
  25    end
  26    
  27    def build_xml(node)
  28      previous_name = ''
  29      node.each_child do |child| 
  30        if child.length > 1 
  31          build_template(child.name)
  32          build_xml(child) 
  33        else
  34          build_value(child.name) if child.name != previous_name
  35          previous_name = child.name
  36        end
  37      end
  38    end
  39        
  40    def build_template(element)
  41      puts '  ' + "<select name=\"#{element}\" />"
  42      puts "</template>"
  43      puts "<template name=\"#{element}\">"
  44    end
  45  
  46    def build_value(element)
  47      puts '  ' + "<value name=\"#{element}\" />"
  48    end
  49  
  50    if __FILE__ == $0
  51      xml_language = '<languages><programming><name>C++</name><name>C Sharp</name
  52  ><name>Ruby</name></programming></languages>'
  53      doc = Document.new(xml_language)
  54      px = PreXml2Xsl.new
  55      px.pre_xml2xsl(doc)
  56    end
  57  end

file: xml2xsl.xml (output from xml2xsl.rb)
   1  
   2  <xsl>
   3    <template name="languages">
   4      <select name="programming"/>
   5    </template>
   6    <template name="programming">
   7      <value name="name"/>
   8    </template>
   9  </xsl>

file: xml2xsl.xsl (used with xml2xsl.xml)
   1  
   2  <?xml version="1.0" encoding="UTF-8"?>
   3  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   4  
   5    <xsl:template match="xsl">
   6    <xsl:variable name="colon"><xsl:text>:</xsl:text></xsl:variable>
   7      <xsl:element name="xsl:stylesheet">
   8        <xsl:attribute name="xmlns{$colon}xsl">
   9          <xsl:text>http://www.w3.org/1999/XSL/Transform</xsl:text>
  10        </xsl:attribute>
  11        <xsl:attribute name="version">
  12          <xsl:text>1.0</xsl:text>
  13        </xsl:attribute>
  14        
  15        <xsl:apply-templates select="*" />
  16      
  17    </xsl:element>
  18  
  19    </xsl:template>
  20    
  21    <xsl:template match="template">
  22    <xsl:text>
  23    </xsl:text>
  24          <xsl:element name="xsl:template">
  25          <xsl:attribute name="match">
  26            <xsl:value-of select="@name"/>
  27          </xsl:attribute>
  28  
  29          <xsl:apply-templates select="*" />
  30    <xsl:text>
  31    </xsl:text>
  32      </xsl:element>
  33  <xsl:text>
  34  </xsl:text>
  35  
  36    </xsl:template>
  37    
  38    <xsl:template match="select">
  39      <xsl:text>
  40      </xsl:text>
  41    <xsl:element name="xsl:element">
  42      <xsl:attribute name="name">
  43        <xsl:value-of select="@name"/>
  44      </xsl:attribute>
  45      <xsl:text>
  46      </xsl:text>
  47      <xsl:text>  </xsl:text><xsl:element name="xsl:apply-templates">
  48        <xsl:attribute name="select">
  49          <xsl:value-of select="@name"/>
  50        </xsl:attribute>
  51      </xsl:element>
  52      <xsl:text>
  53      </xsl:text>
  54    </xsl:element>
  55  
  56  
  57    </xsl:template>
  58    
  59    <xsl:template match="value">
  60      <xsl:text>
  61      </xsl:text>
  62    <xsl:element name="xsl:element">
  63      <xsl:attribute name="name">
  64        <xsl:value-of select="@name"/>
  65      </xsl:attribute>
  66        <xsl:text>
  67        </xsl:text>
  68      <xsl:element name="xsl:value-of">
  69        <xsl:attribute name="select">
  70          <xsl:value-of select="@name"/>
  71        </xsl:attribute>
  72      </xsl:element>
  73      <xsl:text>
  74      </xsl:text>
  75    </xsl:element>
  76  </xsl:template>
  77  </xsl:stylesheet>

output from xml2xsl.xsl
   1  
   2  <?xml version="1.0"?>
   3  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   4    <xsl:template match="languages">
   5      <xsl:element name="programming">
   6        <xsl:apply-templates select="programming"/>
   7      </xsl:element>
   8    </xsl:template>
   9  
  10    <xsl:template match="programming">
  11      <xsl:element name="name">
  12        <xsl:value-of select="name"/>
  13      </xsl:element>
  14    </xsl:template>
  15  </xsl:stylesheet>

Create a crontab entry using XML

This code creates a formatted crontab entry using the files crontab.xml, and crontab_txt.xsl. It is intended that all cron jobs could be stored in the crontab.xml file and then passed to the crontab.

file: crontab_txt.xsl
   1  
   2  <?xml version="1.0" encoding="UTF-8"?>
   3  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   4  <xsl:output method="text"/>
   5  
   6    <xsl:template match="crontab_entry">
   7  
   8    <xsl:apply-templates select="minutes"/>
   9    <xsl:apply-templates select="hours"/>
  10    <xsl:apply-templates select="day_of_month"/>
  11    <xsl:apply-templates select="months"/>
  12    <xsl:apply-templates select="day_of_week"/>
  13  
  14    <xsl:value-of select="command" />
  15    </xsl:template>
  16    
  17    <xsl:template match="minutes">
  18      <xsl:apply-templates select="minute"/>
  19      <xsl:if test="not(minute) or minute=''">*</xsl:if>
  20      <xsl:call-template name="format_unit" />
  21    </xsl:template>
  22    
  23    <xsl:template match="hours">
  24      <xsl:apply-templates select="hour"/>
  25      <xsl:if test="not(hour) or hour=''">*</xsl:if>
  26      <xsl:call-template name="format_unit" />
  27    </xsl:template>
  28    
  29    <xsl:template match="day_of_month">
  30      <xsl:apply-templates select="day"/>
  31      <xsl:if test="not(day) or day=''">*</xsl:if>
  32      <xsl:call-template name="format_unit" />
  33    </xsl:template>
  34    
  35    <xsl:template match="day_of_week">
  36      <xsl:apply-templates select="day"/>
  37      <xsl:if test="not(day) or day=''">*</xsl:if>
  38      <xsl:call-template name="format_unit" />
  39    </xsl:template>
  40    
  41    <xsl:template match="months">
  42      <xsl:apply-templates select="month"/>
  43      <xsl:if test="not(month) or month=''">*</xsl:if>
  44      <xsl:call-template name="format_unit" />
  45    </xsl:template>
  46      
  47    <xsl:template match="month">
  48      <xsl:call-template name="format_value" />
  49    </xsl:template>
  50    
  51    <xsl:template match="day">
  52      <xsl:call-template name="format_value" />
  53    </xsl:template>
  54    
  55    <xsl:template match="hour">
  56      <xsl:call-template name="format_value" />
  57    </xsl:template>
  58    
  59    <xsl:template match="minute">
  60      <xsl:call-template name="format_value" />
  61    </xsl:template>
  62    
  63    <xsl:template name="format_value">
  64      <xsl:value-of select="."/>
  65      <xsl:if test="not(position() =last())"><xsl:text>,</xsl:text>
  66      </xsl:if>
  67    </xsl:template>
  68    
  69    <xsl:template name="format_unit">
  70      <xsl:call-template name="recurring" />
  71      <xsl:text> </xsl:text>
  72    </xsl:template>
  73    
  74    <xsl:template name="recurring">
  75      <xsl:if test="@every">/<xsl:value-of select="@every"/>
  76      </xsl:if>
  77    </xsl:template>
  78    
  79  </xsl:stylesheet>

file: crontab.xml
   1  
   2  <crontab_entry>
   3    <minutes/>
   4    <hours every="3">
   5    <day_of_month>
   6      <day>3</day>
   7      <day>10</day>
   8      <day>15</day>
   9    </day_of_month>
  10    <months/>
  11    <day_of_week/>
  12    <command>ssh james@192.168.1.220 runjob.sh</command>
  13  </crontab_entry>

output: * */3 3,10,15 * * ssh james@192.168.1.220 runjob.sh

A helpful crontab.xml template
   1  
   2  <cron>
   3    <minutes>
   4      <!-- minute (0 - 59) -->
   5      <minute></minute>
   6    </minutes
   7    <hours>
   8      <!-- hour (0 -23) -->
   9      <hour></hour>
  10    </hours>
  11    <day_of_month>
  12      <!-- day of month (1 - 31) -->
  13      <day></day>
  14    </day_of_month>
  15    <months>
  16      <!-- month (1 - 12) -->
  17      <month></month>
  18    </months>
  19    <day_of_week>
  20     <!-- day of week (0 - 6) (Sunday=0 or 7) -->
  21     <day></day>
  22    </day_of_week>
  23    <command></command>
  24  </cron>

Supplying parameters to Ruby XSLT

Here the parameters are supplied as a hash, and if the parameters are not supplied the method will process the xml, and xsl files as normal.

   1  
   2  require 'xml/xslt'
   3  
   4  class Projxslt
   5    
   6    def initialize(sxml, sxsl)
   7      @sxml = sxml
   8      @sxsl = sxsl
   9    end
  10  
  11    def transform(h=nil)
  12      begin
  13      xslt = XML::XSLT.new() 
  14      xslt.xml = @sxml
  15      xslt.xsl = @sxsl
  16  
  17      if not h.nil? then xslt.parameters = h end
  18      out = xslt.serve()
  19      out
  20      
  21      rescue
  22        puts 'problem with xslt data'
  23      end
  24    end
  25  
  26  end
  27  
  28  if __FILE__ == $0
  29      h = Hash.new
  30      h["id"] = '1'
  31      puts h
  32      pxsl = Projxslt.new("../recordx/recordx.xml", "../xsl/recordx.xsl")
  33      puts pxsl.transform(h)
  34  end

Generate Ruby code using XML and XSL

This XSL code transforms an XML file into a basic Ruby file. See the previous post ('Transforming an XML file into an XSL file' http://snipr.com/1usrh [dzone.com]) for an example of the XML used.

   1  
   2  <?xml version="1.0" encoding="UTF-8"?>
   3  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   4  <xsl:output method="text"/>
   5  
   6    <xsl:template match="recordx">
   7    <xsl:variable name="project" select="summary/project" />
   8    <xsl:variable name="parent_element" select="summary/parent_element" />
   9    <xsl:text>#!/usr/bin/ruby
  10  #file: </xsl:text><xsl:value-of select="$project"/><xsl:text>.rb
  11  
  12  require 'recordx'
  13  
  14  class </xsl:text><xsl:value-of select="$project"/><xsl:text> &lt; RecordX
  15  
  16    def initialize()
  17      @project = "</xsl:text><xsl:value-of select="$project"/><xsl:text>"
  18      @parent_element = '</xsl:text><xsl:value-of select="$parent_element"/><xsl:text>fields'
  19      @proj = Projxml.new
  20      @doc_vrecord = initialize_xml_class(SERVER_URL + '/' + @project + '/class_template.xml')
  21      @doc_file = get_doc()
  22    end
  23    
  24  end
  25  
  26  if __FILE__ == $0
  27      r = </xsl:text><xsl:value-of select="$project"/><xsl:text>.new()
  28  end
  29    </xsl:text>
  30    </xsl:template>
  31    
  32  </xsl:stylesheet>

Transform an XML document with XSLT

// Transform an XML file into HTML using XSLT. sources: Ruby/XSLT - http://urltea.com/1nql ruby-talk-google - http://urltea.com/1nqm

   1  
   2