#!/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>