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 11-20 of 21 total

Formatting a date in XSLT

This template formats a date ie 060208171320 -> 06-Feb-08T17:13:20

  <xsl:template name="FormatDate">
    <xsl:param name="DateTime" />
    <!-- new date format 2006-01-14T08:55:22 -->
    <xsl:variable name="mo">
      <xsl:value-of select="substring($DateTime,3,2)" />
    </xsl:variable>
    <xsl:variable name="day">
      <xsl:value-of select="substring($DateTime,5,2)" />
    </xsl:variable>
    <xsl:variable name="year">
      <xsl:value-of select="substring($DateTime,1,2)" />
    </xsl:variable>
    <xsl:variable name="hh">
      <xsl:value-of select="substring($DateTime,7,2)" />
    </xsl:variable>
    <xsl:variable name="mm">
      <xsl:value-of select="substring($DateTime,9,2)" />
    </xsl:variable>
    <xsl:variable name="ss">
      <xsl:value-of select="substring($DateTime,11,2)" />
    </xsl:variable>
    <xsl:if test="(string-length($day) &lt; 2)">
      <xsl:value-of select="0"/>
    </xsl:if>
    <xsl:value-of select="$day"/>
    <xsl:value-of select="'-'"/>
    <xsl:choose>
      <xsl:when test="$mo = '01'">Jan</xsl:when>
      <xsl:when test="$mo = '02'">Feb</xsl:when>
      <xsl:when test="$mo = '03'">Mar</xsl:when>
      <xsl:when test="$mo = '04'">Apr</xsl:when>
      <xsl:when test="$mo = '05'">May</xsl:when>
      <xsl:when test="$mo = '06'">Jun</xsl:when>
      <xsl:when test="$mo = '07'">Jul</xsl:when>
      <xsl:when test="$mo = '08'">Aug</xsl:when>
      <xsl:when test="$mo = '09'">Sep</xsl:when>
      <xsl:when test="$mo = '10'">Oct</xsl:when>
      <xsl:when test="$mo = '11'">Nov</xsl:when>
      <xsl:when test="$mo = '12'">Dec</xsl:when>
    </xsl:choose>
    <xsl:value-of select="'-'"/>

    <xsl:value-of select="$year"/>
    <xsl:value-of select="'T'"/>
    <xsl:value-of select="$hh"/>
    <xsl:value-of select="':'"/>
    <xsl:value-of select="$mm"/>
    <xsl:value-of select="':'"/>
    <xsl:value-of select="$ss"/>
  </xsl:template>


copied from http://snipr.com/1z833 [geekswithblogs.net] and modified to suit the date input format I used.

Substring functions in XSLT

Examples of string functions (substring,substring-after, and substring-before) in XSLT.
substring("ready1234",2,4)
=> eady 
substring("ready1234", 4)
=> dy1234

substring-after("ready1234","y")
=> 1234

substring-before("ready1234","1")
=> ready


reference: X Lab: String functions [zvong.org]

Transforming XML into RSS

Using the previous code snippet which prepared an XML file it can now be transformed to RSS using the XSL below.


file: gang2rss.xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

	<xsl:output method="xml" encoding="iso-8859-1" indent="yes"  />

	<xsl:template match="rss">

		<rss version="2.0">	
		<channel>
		<title>The Gang</title>
		<link>http://newsgang.net/audio/</link>
		<description>The Gang podcast</description>

  	<language>en</language>

	<xsl:apply-templates select="item" />

		</channel>
		</rss>

	</xsl:template>

	<xsl:template match="item">

	<item>
		<title><xsl:value-of select="title"/></title>
		<link>http://newsgang.net<xsl:value-of select="href"/></link>
		<description><xsl:value-of select="date"/></description>
		<enclosure>http://newsgang.net<xsl:value-of select="href_audio"/></enclosure>
	</item>

	</xsl:template>	

</xsl:stylesheet>


To transform the xsl file from the command-line you would type:

xsltproc gang2rss.xsl thegang_rss.xml

output
<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
  <channel>
    <title>The Gang</title>
    <link>http://newsgang.net/audio/</link>
    <description>The Gang podcast</description>
    <language>en</language>
    <item>
      <title>TheGangXII-II</title>
      <link>http://newsgang.net/gangitem/id=6501</link>
      <description>Jan 25</description>
      <enclosure>http://newsgang.net/gangitem/id=6501&amp;from=audio</enclosure>
    </item>
    <item>
      <title>TheGangXII-I</title>
      <link>http://newsgang.net/gangitem/id=6499</link>
      <description>Jan 25</description>
      <enclosure>http://newsgang.net/gangitem/id=6499&amp;from=audio</enclosure>
    </item>
    <item>
      <title>NewsGangLive01.24.08</title>
      <link>http://newsgang.net/gangitem/id=6445</link>
      <description>Jan 24</description>
      <enclosure>http://newsgang.net/gangitem/id=6445&amp;from=audio</enclosure>
    </item>
    <item>
      <title>NewsGangLiveII</title>
      <link>http://newsgang.net/gangitem/id=6377</link>
      <description>Jan 23</description>
      <enclosure>http://newsgang.net/gangitem/id=6377&amp;from=audio</enclosure>
    </item>
  </channel>
</rss>

Note: The enclosure url in this example does not reference the media file directly.

see also: http://en.wikipedia.org/wiki/RSS_(file_format)

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
<?xml version="1.0"?>

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      
    <xsl:template match="car_log">
      <div>      
        <p>Total miles this month: <xsl:value-of select="sum(records/entry/miles)" /></p>
        <xsl:apply-templates select="records"/>
      </div>
    </xsl:template>
    
    <xsl:template match="car_log/records/entry"><xsl:variable name="pos" select="position()"/>
    <div class="record">
      <dl>
        <dt><label for="trip"><xsl:value-of select="@title"/>trip</label></dt>
        <dd>
          <input type="text" id="trip{$pos}" name="trip{$pos}" value="{trip}" size="{@size}" />
        </dd>
          
        <dt><label for="miles"><xsl:value-of select="@title"/>miles</label></dt>
        <dd>
          <input type="text" id="miles{$pos}" name="miles{$pos}" value="{miles}" size="2" />
        </dd>
          
        <dt><label for="description"><xsl:value-of select="@title"/>description</label></dt>
        <dd>
          <input type="text" id="description{$pos}" name="description{$pos}" value="{description}"  />
        </dd>        
      </dl>
    </div>
    </xsl:template>
    </xsl:stylesheet>

file: car_log.xml
<car_log>
  <summary>
    <project>car_log</project>
  </summary>
  <records>
    <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>
    <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>
    <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>
    <entry id='18174'><date>Thu Dec 20 01:34:26 +0000 2007</date><trip>visiting parents</trip><miles>12.7</miles><description/>
    </entry>
  </records>
</car_log>

output
Total miles this month: 59.1
...

Zebra stripes on rows using XSLT

Using XSL every 2nd row will contain the class named 'stripe'.
  <xsl:element name="li">
        <xsl:if test="(position() mod 2) != 1">
          <xsl:attribute name="class"><xsl:text>stripe</xsl:text></xsl:attribute>
	</xsl:if>
  </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.

require 'rexml/document'
include REXML

  def pretty_print(parent_node, itab)
    buffer = ''

    parent_node.elements.each do |node|

      buffer += ' ' * itab + "<#{node.name}#{get_att_list(node)}"
  
      if node.to_a.length > 0
        buffer += ">"
        if node.text.nil?
          buffer += "\n"
          buffer += pretty_print(node,itab+2) 
          buffer += ' ' * itab + "</#{node.name}>\n"
        else
          node_text = node.text.strip
          if node_text != ''
            buffer += node_text 
            buffer += "</#{node.name}>\n"        
          else
            buffer += "\n" + pretty_print(node,itab+2) 
            buffer += ' ' * itab + "</#{node.name}>\n"        
          end
        end
      else
        buffer += "/>\n"
      end
      
    end
    buffer
  end

  def get_att_list(node)
    att_list = ''
    node.attributes.each { |attribute, val| att_list += " #{attribute}='#{val}'" }
    att_list
  end
  
  def pretty_xml(doc)
    buffer = ''
    xml_declaration = doc.to_s.match('<\?.*\?>').to_s
    buffer += "#{xml_declaration}\n" if not xml_declaration.nil?
    xml_doctype = doc.to_s.match('<\!.*\">').to_s
    buffer += "#{xml_doctype}\n" if not xml_doctype.nil?
    buffer += "<#{doc.root.name}#{get_att_list(doc.root)}"
    if doc.root.to_a.length > 0
      buffer +=">\n#{pretty_print(doc.root,2)}</#{doc.root.name}>"
    else
      buffer += "/>\n"
    end
  end

xml_data = "<hi id='124'><yo><a id='1'/><b/><c/></yo><sushi><love>Ruby</love></sushi></hi>"
doc = Document.new(xml_data)
pretty_xml(doc)


output
<hi id='124'>
  <yo>
    <a id='1'/>
    <b/>
    <c/>
  </yo>
  <sushi>
    <love>Ruby</love>
  </sushi>
</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*
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="ISO-8859-1"/>
  <xsl:param name="indent-increment" select="'   '"/>
  
  <xsl:template name="newline">
    <xsl:text disable-output-escaping="yes">
</xsl:text>
  </xsl:template>
  
  <xsl:template match="comment() | processing-instruction()">
    <xsl:param name="indent" select="''"/>
    <xsl:call-template name="newline"/>    
    <xsl:value-of select="$indent"/>
    <xsl:copy />
  </xsl:template>
  
  <xsl:template match="text()">
    <xsl:param name="indent" select="''"/>
    <xsl:call-template name="newline"/>    
    <xsl:value-of select="$indent"/>
    <xsl:value-of select="normalize-space(.)"/>
  </xsl:template>
    
  <xsl:template match="text()[normalize-space(.)='']"/>
  
  <xsl:template match="*">
    <xsl:param name="indent" select="''"/>
    <xsl:call-template name="newline"/>    
    <xsl:value-of select="$indent"/>
      <xsl:choose>
       <xsl:when test="count(child::*) > 0">
        <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates select="*|text()">
           <xsl:with-param name="indent" select="concat ($indent, $indent-increment)"/>
         </xsl:apply-templates>
         <xsl:call-template name="newline"/>
         <xsl:value-of select="$indent"/>
        </xsl:copy>
       </xsl:when>       
       <xsl:otherwise>
        <xsl:copy-of select="."/>
       </xsl:otherwise>
     </xsl:choose>
  </xsl:template>    
</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.
#!/usr/bin/ruby
# file: xml2xsl.rb

# author: jrobertson
# created: 31-Dec-07
# description: 
#   Converts an xml file into another xml file in 'xml2xsl' format.
#   This new xml file can then be transformed with the stylesheet 
#   xml2xsl.xsl into a multi-purpose xsl file template for the original 
#   xml file.

 
require 'rexml/document'
include REXML

class PreXml2Xsl

  def pre_xml2xsl(doc)
    puts '<xsl>'
    puts "  <template name='" + doc.root.name + "'>"
    build_xml(doc.root)
    puts '    </template>'
    puts '</xsl>'
  end
  
  def build_xml(node)
    previous_name = ''
    node.each_child do |child| 
      if child.length > 1 
        build_template(child.name)
        build_xml(child) 
      else
        build_value(child.name) if child.name != previous_name
        previous_name = child.name
      end
    end
  end
      
  def build_template(element)
    puts '  ' + "<select name=\"#{element}\" />"
    puts "</template>"
    puts "<template name=\"#{element}\">"
  end

  def build_value(element)
    puts '  ' + "<value name=\"#{element}\" />"
  end

  if __FILE__ == $0
    xml_language = '<languages><programming><name>C++</name><name>C Sharp</name
><name>Ruby</name></programming></languages>'
    doc = Document.new(xml_language)
    px = PreXml2Xsl.new
    px.pre_xml2xsl(doc)
  end
end

file: xml2xsl.xml (output from xml2xsl.rb)
<xsl>
  <template name="languages">
    <select name="programming"/>
  </template>
  <template name="programming">
    <value name="name"/>
  </template>
</xsl>

file: xml2xsl.xsl (used with xml2xsl.xml)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="xsl">
  <xsl:variable name="colon"><xsl:text>:</xsl:text></xsl:variable>
    <xsl:element name="xsl:stylesheet">
      <xsl:attribute name="xmlns{$colon}xsl">
        <xsl:text>http://www.w3.org/1999/XSL/Transform</xsl:text>
      </xsl:attribute>
      <xsl:attribute name="version">
        <xsl:text>1.0</xsl:text>
      </xsl:attribute>
      
      <xsl:apply-templates select="*" />
    
  </xsl:element>

  </xsl:template>
  
  <xsl:template match="template">
  <xsl:text>
  </xsl:text>
        <xsl:element name="xsl:template">
        <xsl:attribute name="match">
          <xsl:value-of select="@name"/>
        </xsl:attribute>

        <xsl:apply-templates select="*" />
  <xsl:text>
  </xsl:text>
    </xsl:element>
<xsl:text>
</xsl:text>

  </xsl:template>
  
  <xsl:template match="select">
    <xsl:text>
    </xsl:text>
  <xsl:element name="xsl:element">
    <xsl:attribute name="name">
      <xsl:value-of select="@name"/>
    </xsl:attribute>
    <xsl:text>
    </xsl:text>
    <xsl:text>  </xsl:text><xsl:element name="xsl:apply-templates">
      <xsl:attribute name="select">
        <xsl:value-of select="@name"/>
      </xsl:attribute>
    </xsl:element>
    <xsl:text>
    </xsl:text>
  </xsl:element>


  </xsl:template>
  
  <xsl:template match="value">
    <xsl:text>
    </xsl:text>
  <xsl:element name="xsl:element">
    <xsl:attribute name="name">
      <xsl:value-of select="@name"/>
    </xsl:attribute>
      <xsl:text>
      </xsl:text>
    <xsl:element name="xsl:value-of">
      <xsl:attribute name="select">
        <xsl:value-of select="@name"/>
      </xsl:attribute>
    </xsl:element>
    <xsl:text>
    </xsl:text>
  </xsl:element>
</xsl:template>
</xsl:stylesheet>

output from xml2xsl.xsl
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="languages">
    <xsl:element name="programming">
      <xsl:apply-templates select="programming"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="programming">
    <xsl:element name="name">
      <xsl:value-of select="name"/>
    </xsl:element>
  </xsl:template>
</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
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>

  <xsl:template match="crontab_entry">

  <xsl:apply-templates select="minutes"/>
  <xsl:apply-templates select="hours"/>
  <xsl:apply-templates select="day_of_month"/>
  <xsl:apply-templates select="months"/>
  <xsl:apply-templates select="day_of_week"/>

  <xsl:value-of select="command" />
  </xsl:template>
  
  <xsl:template match="minutes">
    <xsl:apply-templates select="minute"/>
    <xsl:if test="not(minute) or minute=''">*</xsl:if>
    <xsl:call-template name="format_unit" />
  </xsl:template>
  
  <xsl:template match="hours">
    <xsl:apply-templates select="hour"/>
    <xsl:if test="not(hour) or hour=''">*</xsl:if>
    <xsl:call-template name="format_unit" />
  </xsl:template>
  
  <xsl:template match="day_of_month">
    <xsl:apply-templates select="day"/>
    <xsl:if test="not(day) or day=''">*</xsl:if>
    <xsl:call-template name="format_unit" />
  </xsl:template>
  
  <xsl:template match="day_of_week">
    <xsl:apply-templates select="day"/>
    <xsl:if test="not(day) or day=''">*</xsl:if>
    <xsl:call-template name="format_unit" />
  </xsl:template>
  
  <xsl:template match="months">
    <xsl:apply-templates select="month"/>
    <xsl:if test="not(month) or month=''">*</xsl:if>
    <xsl:call-template name="format_unit" />
  </xsl:template>
    
  <xsl:template match="month">
    <xsl:call-template name="format_value" />
  </xsl:template>
  
  <xsl:template match="day">
    <xsl:call-template name="format_value" />
  </xsl:template>
  
  <xsl:template match="hour">
    <xsl:call-template name="format_value" />
  </xsl:template>
  
  <xsl:template match="minute">
    <xsl:call-template name="format_value" />
  </xsl:template>
  
  <xsl:template name="format_value">
    <xsl:value-of select="."/>
    <xsl:if test="not(position() =last())"><xsl:text>,</xsl:text>
    </xsl:if>
  </xsl:template>
  
  <xsl:template name="format_unit">
    <xsl:call-template name="recurring" />
    <xsl:text> </xsl:text>
  </xsl:template>
  
  <xsl:template name="recurring">
    <xsl:if test="@every">/<xsl:value-of select="@every"/>
    </xsl:if>
  </xsl:template>
  
</xsl:stylesheet>

file: crontab.xml
<crontab_entry>
  <minutes/>
  <hours every="3">
  <day_of_month>
    <day>3</day>
    <day>10</day>
    <day>15</day>
  </day_of_month>
  <months/>
  <day_of_week/>
  <command>ssh james@192.168.1.220 runjob.sh</command>
</crontab_entry>

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

A helpful crontab.xml template
<cron>
  <minutes>
    <!-- minute (0 - 59) -->
    <minute></minute>
  </minutes
  <hours>
    <!-- hour (0 -23) -->
    <hour></hour>
  </hours>
  <day_of_month>
    <!-- day of month (1 - 31) -->
    <day></day>
  </day_of_month>
  <months>
    <!-- month (1 - 12) -->
    <month></month>
  </months>
  <day_of_week>
   <!-- day of week (0 - 6) (Sunday=0 or 7) -->
   <day></day>
  </day_of_week>
  <command></command>
</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.

require 'xml/xslt'

class Projxslt
  
  def initialize(sxml, sxsl)
    @sxml = sxml
    @sxsl = sxsl
  end

  def transform(h=nil)
    begin
    xslt = XML::XSLT.new() 
    xslt.xml = @sxml
    xslt.xsl = @sxsl

    if not h.nil? then xslt.parameters = h end
    out = xslt.serve()
    out
    
    rescue
      puts 'problem with xslt data'
    end
  end

end

if __FILE__ == $0
    h = Hash.new
    h["id"] = '1'
    puts h
    pxsl = Projxslt.new("../recordx/recordx.xml", "../xsl/recordx.xsl")
    puts pxsl.transform(h)
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.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>

  <xsl:template match="recordx">
  <xsl:variable name="project" select="summary/project" />
  <xsl:variable name="parent_element" select="summary/parent_element" />
  <xsl:text>#!/usr/bin/ruby
#file: </xsl:text><xsl:value-of select="$project"/><xsl:text>.rb

require 'recordx'

class </xsl:text><xsl:value-of select="$project"/><xsl:text> &lt; RecordX

  def initialize()
    @project = "</xsl:text><xsl:value-of select="$project"/><xsl:text>"
    @parent_element = '</xsl:text><xsl:value-of select="$parent_element"/><xsl:text>fields'
    @proj = Projxml.new
    @doc_vrecord = initialize_xml_class(SERVER_URL + '/' + @project + '/class_template.xml')
    @doc_file = get_doc()
  end
  
end

if __FILE__ == $0
    r = </xsl:text><xsl:value-of select="$project"/><xsl:text>.new()
end
  </xsl:text>
  </xsl:template>
  
</xsl:stylesheet>
« Newer Snippets
Older Snippets »
Showing 11-20 of 21 total