Something just occured to me as far as a really useful way of using the “meta-data” obtained during the recursive processing of a sequence of nodes. Take for example the following use-case:
Contained within the test-suite code I posted a week or two ago is contained a combination of XML and XSL files. In the config-bat-output.xml file the following XML structure and data exists:
<?xml version="1.0"?>
<output>
<files>
<source href="test-group.xml"/>
</files>
<defaults>
<processor id="saxon" call="Saxon8.jar">Saxon 8.1.1 form Saxonica</processor>
<platform id="java" call="java">Java 1.4.2_4 from Sun Micrososystems</platform>
<command-line id="cmdln" default-switch="-">
<switch call-id="java" no-switch="true"/>
<switch value="ms" multiple-of="1024" use="512m">Sets the minimum heap size for the Java VM</switch>
<switch value="mx" multiple-of="1024" use="512m">Sets the maximum heap size for the Java VM</switch>
<switch value="jar">Tells the Java VM to use the Java Archive option</switch>
<switch call-id="saxon" no-switch="true"/>
</command-line>
</defaults>
<sequence>
<node call-id="cmdln" />
<node>t</node>
<node>o</node>
<node>in-xml</node>
<node>in-xsl</node>
<node>capture-t</node>
</sequence>
<sequence>
<node call-id="cmdln" />
<node>t</node>
<node>3</node>
<node>o</node>
<node>in-xml</node>
<node>in-xsl</node>
<node>capture-t</node>
</sequence>
<sequence>
<node call-id="cmdln" />
<node>t</node>
<node>9</node>
<node>o</node>
<node>in-xml</node>
<node>in-xsl</node>
<node>capture-t</node>
</sequence>
</output>
Within this data structure exists a series of processes to invoke during the transformation in which there is a default set of data that goes along with each subsequent combination of sequences. Within the “defaults” element is contained a series of elements in which the name of each element is used by the stylesheet to invoke a particular type of text output. NOTE: I plan further to use the AspectXML data weaving engine that I built nearly a year ago, slightly modified, to further use an XML definition file to determine the output instead of “hardcoding” this information within the stylesheet. The ultimate goal of course is to be able to quickly and easily update particular aspects of an XML-based application and have these updates automagically reverberate throughout the entire code-base. All very possible but all in which time is needed to build the code and “Tiiiiiiiiiiiiimmmme is not on my side, no it’s not” at the moment. It will be though and this particular project will be seeing some serious dev-time by Russ and myself in the very near future :D
So anyways, long code explanation made short: Within each element is contained the ability to invoke a predefined sequence of elements by simply using the call-id attribute with the id of the sequence to invoke (any resemblance to Lisp is absolutely, totally, 100% intentional … if you are aware of some of my other projects then you can probably see where I intend to take this but for now its simply just sample code :D ;)).
When the stylesheet process is invoked the above file is “woven” together with the following xml data-set:
<?xml version="1.0"?>
<files>
<xsl-files>
<file identifier="b" name="test-group.xsl"/>
<file identifier="m" name="test-group-m.xsl"/>
</xsl-files>
<config-files>
<file id="bat-config" name="config-bat-output.xml"/>
</config-files>
<output-files>
<file number-of-elements="100"/>
<file number-of-elements="200"/>
<file number-of-elements="500"/>
<file number-of-elements="1000"/>
<file number-of-elements="2000"/>
<file number-of-elements="6400"/>
<file number-of-elements="12800"/>
<file number-of-elements="25600"/>
</output-files>
</files>
This file basically defines another series of sequences that need to take place in order to obtain the final resulting output of test files, each of which contains the specified number of elements (+/- based on using the round function to obtain the general number of recursive calls that need to be made to get the correct number of elements copied into each test file — this could be modified to be completely accurate but for this particular case being +/- a few elements here and there is not important as long as the same number is used for all stylesheet test cases).
Ultimatelly each sequence of recursive calls can have any number of additional recursive calls to other “functions” and so on and so forth. In the end the total number of recursive calls can become quite substantial making it difficult to know whether or not the correct sequences were called during the transformation process. Of course using a Schema Aware processor such as Saxon SA would at least make the debuggin process A LOT easier but thats not where I am taking this particular post so bear with me for one more second.
If, for example, this series of recursive function calls represented a user-invoked function that performed a series of sub-routines in which ultimatelly converted 250,000 randomly placed pixels from one RGB value to another or furthermore converted 250,000,000 such pixels into various shades of a particular RGB value how much easier would life be if we could have a “copy” of all the processes that took place during that series of sub-routines such that we could undo a certain percentage of these changes to vary the shading of an image to various levels. Such a programming task using an object oriented approach is a NIGHTMARE at best. But in this particular scenario would be a piece of cake given the fact that the meta-data captured during each process could easily be backed out or right back in and our code base wouldn’t need to know the difference. Its just repeating a series of recursive function calls, it could care less where they came from or how they got there.
Just food for thought…
Enjoy :)
BTW… In case you are curious as to what the XSL looks like to process the above XML files and yet don’t want to have to download, unzip, and open them up locally here it is:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<!-- This Stylesheet is licensed under the Creative Commons 2.0 Attribution License -->
<!-- For more information in regards to this license please visit the following URL -->
<!-- http://creativecommons.org/licenses/by/2.0/ -->
<!-- Original Author: M. David Peterson -->
<!-- Original Author's Contact Email: m.david@x2x2x.org -->
<!-- Original Author's Web Address: http://www.xsltblog.com -->
<!-- Original Release Date: December 20th, 2004 -->
<!-- Version Information: 0.1 -->
<!-- Any questions, comments, or concerns please visit my XSLT related blog at the address posted above. -->
<!-- This stylesheet requires a processor that supports the latest workking draft of the XSLT 2.0 specification -->
<!-- While there are several that are near completion and several more well on their way, the only processor -->
<!-- that can be considered completely up-to-date with the latest working draft specification -->
<!-- is Dr. Michaels Kays latest Saxon processor release. Please visit http://www.Saxonica.com for more details -->
<!-- Enjoy! -->
<!-- <M:D/> -->
<xsl:param name="output"/>
<xsl:param name="result-parent"/>
<xsl:param name="parent-bat-file"/>
<xsl:param name="execution-directory"/>
<xsl:variable name="bat-source-file" select="document(/files/config-files/file[@id = 'bat-config']/@name)"/>
<xsl:variable name="source-file" select="document($bat-source-file/output/files/source/@href)"/>
<xsl:variable name="source-file-elements" select="$source-file/booklist/book"/>
<xsl:variable name="defaults" select="$bat-source-file/output/defaults"/>
<xsl:variable name="xsl-file-names" select="/files/xsl-files"/>
<xsl:output name="text" method="text" encoding="utf-8"/>
<xsl:output name="xml" method="xml"/>
<xsl:template match="/">
<xsl:result-document format="text" href="file:///{$output}/{$parent-bat-file}">
<xsl:text>rem This is the beginning of the final output batch file that will
</xsl:text>
<xsl:text>rem automatically run the other batch files created during this process.
</xsl:text>
</xsl:result-document>
<xsl:apply-templates select="files/output-files/file"/>
</xsl:template>
<xsl:template match="file">
<xsl:variable name="file-name" select="concat(@number-of-elements, '.xml')"/>
<xsl:variable name="bat-file-name" select="concat(@number-of-elements, '.bat')"/>
<xsl:variable name="recurse-source-file-number" select="round(@number-of-elements div count($source-file-elements))"/>
<xsl:result-document href="file:///{$output}/{$file-name}">
<xsl:element name="{$result-parent}">
<xsl:call-template name="add-elements">
<xsl:with-param name="recurse-source-file-number" select="$recurse-source-file-number"/>
</xsl:call-template>
</xsl:element>
</xsl:result-document>
<xsl:apply-templates select="$xsl-file-names/file" mode="xsl-files">
<xsl:with-param name="in-xml-file-name" select="$file-name"/>
<xsl:with-param name="bat-file-name" select="$bat-file-name"/>
<xsl:with-param name="test-output-file-name" select="concat('o-', @number-of-elements, '.xml')"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template name="add-elements">
<xsl:param name="recurse-source-file-number"/>
<xsl:if test="$recurse-source-file-number != 0">
<xsl:copy-of select="$source-file/booklist/book"/>
<xsl:call-template name="add-elements">
<xsl:with-param name="recurse-source-file-number" select="$recurse-source-file-number - 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="file" mode="xsl-files">
<xsl:param name="in-xml-file-name"/>
<xsl:param name="bat-file-name"/>
<xsl:param name="test-output-file-name"/>
<xsl:apply-templates select="$bat-source-file/output/sequence">
<xsl:with-param name="in-xml-file-name" select="$in-xml-file-name"/>
<xsl:with-param name="in-xsl-file-name" select="@name"/>
<xsl:with-param name="identifier" select="@identifier"/>
<xsl:with-param name="bat-file-name" select="$bat-file-name"/>
<xsl:with-param name="test-output-file-name" select="$test-output-file-name"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="sequence">
<xsl:param name="in-xml-file-name"/>
<xsl:param name="in-xsl-file-name"/>
<xsl:param name="identifier"/>
<xsl:param name="bat-file-name"/>
<xsl:param name="test-output-file-name"/>
<xsl:variable name="sequence-bat-file-name" select="concat('s-', position(), '-', $identifier, '-', $bat-file-name)"/>
<xsl:variable name="text-output">
<xsl:variable name="command-line">
<xsl:apply-templates select="$defaults/command-line"/>
</xsl:variable>
<xsl:apply-templates select="node">
<xsl:with-param name="test-output-file-name" select="$test-output-file-name"/>
<xsl:with-param name="in-xml" select="$in-xml-file-name"/>
<xsl:with-param name="in-xsl" select="$in-xsl-file-name"/>
<xsl:with-param name="identifier" select="concat($identifier, '-', position())"/>
<xsl:with-param name="command-line" select="$command-line"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:result-document format="text" href="file:///{$output}/{$sequence-bat-file-name}">
<xsl:value-of select="$text-output"/>
</xsl:result-document>
<xsl:variable name="bat-file-parent-doc">
<xsl:value-of select="unparsed-text(concat('file:///', $output, '/', $parent-bat-file), 'utf-8')"/>
</xsl:variable>
<xsl:result-document format="text" href="file:///{$output}/{$parent-bat-file}">
<xsl:value-of select="$bat-file-parent-doc"/>
<xsl:text>call </xsl:text>
<xsl:value-of select="$sequence-bat-file-name"/>
<xsl:text>
</xsl:text>
</xsl:result-document>
</xsl:template>
<xsl:template match="command-line">
<xsl:apply-templates select="switch">
<xsl:with-param name="default-switch" select="@default-switch"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="node[@call-id]">
<xsl:param name="command-line"/>
<xsl:value-of select="$command-line"/>
</xsl:template>
<xsl:template match="node[. = 'in-xml']">
<xsl:param name="in-xml"/>
<xsl:value-of select="$in-xml"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="switch[@call-id]">
<xsl:param name="default-switch"/>
<xsl:if test="@no-switch = 'false' or not(@no-switch)">
<xsl:value-of select="$default-switch"/>
</xsl:if>
<xsl:value-of select="ancestor::defaults/*[@id = current()/@call-id]/@call"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="switch[@value]">
<xsl:param name="default-switch"/>
<xsl:if test="@no-switch = 'false' or not(@no-switch)">
<xsl:value-of select="$default-switch"/>
</xsl:if>
<xsl:value-of select="@value"/>
<xsl:if test="@use">
<xsl:value-of select="@use"/>
</xsl:if>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="node[. = 'in-xsl']">
<xsl:param name="in-xsl"/>
<xsl:value-of select="$in-xsl"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="node[. = 'o']">
<xsl:param name="test-output-file-name"/>
<xsl:text>-o </xsl:text>
<xsl:value-of select="$test-output-file-name"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="node[. = 't']">
<xsl:text>-t </xsl:text>
</xsl:template>
<xsl:template match="node[. = 'capture-t']">
<xsl:param name="test-output-file-name"/>
<xsl:param name="identifier"/>
<xsl:text>2></xsl:text>
<xsl:value-of select="concat($execution-directory, '\', $test-output-file-name, '-', $identifier)"/>
<xsl:text>.txt</xsl:text>
</xsl:template>
<xsl:template match="node">
<xsl:text>-</xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
BTW… When I wrote this I made the conscious choice not to use the capability contained in XPath 2.0 to use conditional logic statements embedded in the XPath to further reduce the verbosity of XSLT and hyperextend the capabilities to some fairly drastic levels. I did this as to not scare people who were used to using standard XSLT conditional statements with too many changes but I plan to update this code to take advantage of all XSLT 2.0 has to offer in the not too distant future.
The commandline values to invoke this process is as follows:
java -jar saxon8.jar config-test-files.xml build-test-xml.xsl output=C:/test/output result-parent=booklist parent-bat-file=runtests.bat execution-directory=execution-results
TrackBack URL for this entry:
http://www.xsltblog.com/xslt-blog-mt/mt-tb.cgi/277
Listed below are links to weblogs that reference Idea for usage in regards to Dimitre's "meta-data" post:
» Home Equity Loan from Home Equity Loan
Home Equity Loan [Read More]
Tracked on March 4, 2006 03:31 AM
» free ringtones from free ringtones
free ringtones is a niceblogers. [Read More]
Tracked on March 15, 2006 12:09 PM