Unable to generate JavaScript using XSLT
Hi, I have an XML file format and an XSLT format to turn it into a JavaScript file (see below). This works on the command line: ==== $ xsltproc corejet-to-jit.xsl catalogue.xml // corejet-output.js, generated from Corejet Requirements Catalogue var custom_color_for = function(num_passing, num_pending, total) { var weighted = ( num_passing + (0.3 * num_pending) ) / total; var red = (255 * weighted) / 100; var green = (255*(100-weighted)) / 100; if (total==0) { red = 0; green = 0; } return 'rgb('+red+','+green+',0)'; } var metadata = { 'project': 'Test project', 'testTime': '2011-01-02T12:05:00' } var json = { 'id': 'root', 'name': 'Test project', 'data': {}, 'children': [ { 'id': 'epic-E1', 'name': 'First epic', 'data': { '$area': 6 * 10, '$color': custom_color_for(1, 0, 2) }, 'children': [ { 'id': 'story-S1', 'name': 'S1', 'data': { 'title': 'First story', '$area': 3 * 10, '$color': custom_color_for(1, 0, 2) }, 'children': [ { 'id': 'scenario-First scenario', 'name': '', 'data': { 'title': 'First scenario', '$color': '#0a0' , '$area': (3 / 2) * 10, }, 'children': [], }, { 'id': 'scenario-Second scenario', 'name': '', 'data': { 'title': 'Second scenario', '$color': '#a00' , '$area': (3 / 2) * 10, }, 'children': [], }, ] }, { 'id': 'story-S2', 'name': 'S2', 'data': { 'title': 'Second story', '$area': 3 * 10, '$color': custom_color_for(0, 0, 0) }, 'children': [ ] }, ] }, { 'id': 'epic-E2', 'name': 'Second epic', 'data': { '$area': 0 * 10, '$color': custom_color_for(0, 0, 0) }, 'children': [ ] }, ] }; ==== However, I can't apply the transform (or at least read the results) using lxml:
from lxml import etree input = etree.parse(open('catalogue.xml')) xslt = etree.parse(open('corejet-to-jit.xsl')) output = input.xslt(xslt) etree.tostring(output, pretty_print=True) is None True output.getroot() is None True
Why is this? Does it have to do with the slightly unorthodox XSL? Martin catalogue.xml: <requirementscatalogue project="Test project" extractTime="2011-01-02T12:01:00" testTime="2011-01-02T12:05:00"> <epic id="E1" title="First epic"> <story id="S1" title="First story" points="3" requirementStatus="open" priority="high"> <scenario name="First scenario" testStatus="pass"> <given>something</given> <when>something happens</when> <then>do something</then> <then>and something else</then> </scenario> <scenario name="Second scenario" testStatus="mismatch"> <given>something</given> <when>something happens</when> <then>do something</then> <then>and something else</then> </scenario> </story> <story id="S2" title="Second story" points="3" requirementStatus="closed" requirementResolution="fixed" priority="high"/> </epic> <epic id="E2" title="Second epic"/> </requirementscatalogue> corejet-to-jit.xsl: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output omit-xml-declaration="yes"/> <xsl:template match="//requirementscatalogue"> // corejet-output.js, generated from Corejet Requirements Catalogue var custom_color_for = function(num_passing, num_pending, total) { var weighted = ( num_passing + (0.3 * num_pending) ) / total; var red = (255 * weighted) / 100; var green = (255*(100-weighted)) / 100; if (total==0) { red = 0; green = 0; } return 'rgb('+red+','+green+',0)'; } var metadata = { 'project': '<xsl:value-of select="@project"/>', 'testTime': '<xsl:value-of select="@testTime"/>' } var json = { 'id': 'root', 'name': '<xsl:value-of select="@project"/>', 'data': {}, 'children': [ <xsl:apply-templates select="epic"/> ] }; </xsl:template> <xsl:template match="epic"> { 'id': 'epic-<xsl:value-of select="@id"/>', 'name': '<xsl:value-of select="@title"/>', 'data': { '$area': <xsl:value-of select="sum(child::story/@points)"/> * 10, <xsl:variable name="num_passing"><xsl:value-of select="count(story/scenario[@testStatus='pass'])"/></xsl:variable> <xsl:variable name="num_pending"><xsl:value-of select="count(story/scenario[@testStatus='pending'])"/></xsl:variable> <xsl:variable name="total_scenarios"><xsl:value-of select="count(story/scenario)"/></xsl:variable> '$color': custom_color_for(<xsl:number value="$num_passing"/>, <xsl:number value="$num_pending"/>, <xsl:number value="$total_scenarios"/>) }, 'children': [ <xsl:apply-templates select="story"/> ] }, </xsl:template> <xsl:template match="story"> { 'id': 'story-<xsl:value-of select="@id"/>', 'name': '<xsl:value-of select="@id"/>', 'data': { 'title': '<xsl:value-of select="@title"/>', '$area': <xsl:value-of select="@points"/> * 10, <xsl:variable name="num_passing"><xsl:value-of select="count(scenario[@testStatus='pass'])"/></xsl:variable> <xsl:variable name="num_pending"><xsl:value-of select="count(scenario[@testStatus='pending'])"/></xsl:variable> <xsl:variable name="total_scenarios"><xsl:value-of select="count(scenario)"/></xsl:variable> '$color': custom_color_for(<xsl:number value="$num_passing"/>, <xsl:number value="$num_pending"/>, <xsl:number value="$total_scenarios"/>) }, 'children': [ <xsl:apply-templates select="scenario"/> ] }, </xsl:template> <xsl:template match="scenario"> { 'id': 'scenario-<xsl:value-of select="@name"/>', 'name': '', 'data': { 'title': '<xsl:value-of select="@name"/>', '$color': <xsl:choose> <xsl:when test="@testStatus='pass'"> '#0a0' </xsl:when> <xsl:when test="@testStatus='pending'"> '#aa0' </xsl:when> <xsl:otherwise> '#a00' </xsl:otherwise> </xsl:choose>, '$area': (<xsl:value-of select="../@points"/> / <xsl:value-of select="count(../scenario)"/>) * 10, }, 'children': [], }, </xsl:template> </xsl:stylesheet>
On 16 May 2011 13:29, Martin Aspeli <optilude+lists@gmail.com> wrote:
However, I can't apply the transform (or at least read the results) using lxml:
from lxml import etree input = etree.parse(open('catalogue.xml')) xslt = etree.parse(open('corejet-to-jit.xsl')) output = input.xslt(xslt) etree.tostring(output, pretty_print=True) is None True output.getroot() is None True
Why is this? Does it have to do with the slightly unorthodox XSL?
Have you tried adding <xsl:output method="text"/> to your xsl? Laurence
On 16 May 2011 13:47, Laurence Rowe <l@lrowe.co.uk> wrote:
On 16 May 2011 13:29, Martin Aspeli <optilude+lists@gmail.com> wrote:
However, I can't apply the transform (or at least read the results) using lxml:
from lxml import etree input = etree.parse(open('catalogue.xml')) xslt = etree.parse(open('corejet-to-jit.xsl')) output = input.xslt(xslt) etree.tostring(output, pretty_print=True) is None True output.getroot() is None True
Why is this? Does it have to do with the slightly unorthodox XSL?
Have you tried adding <xsl:output method="text"/> to your xsl?
Actually you should also be using str(xslt_result_doc) instead of etree.tostring(xslt_result_doc). Laurence
On 16 May 2011 13:49, Laurence Rowe <l@lrowe.co.uk> wrote:
On 16 May 2011 13:47, Laurence Rowe <l@lrowe.co.uk> wrote:
On 16 May 2011 13:29, Martin Aspeli <optilude+lists@gmail.com> wrote:
However, I can't apply the transform (or at least read the results) using lxml:
from lxml import etree input = etree.parse(open('catalogue.xml')) xslt = etree.parse(open('corejet-to-jit.xsl')) output = input.xslt(xslt) etree.tostring(output, pretty_print=True) is None True output.getroot() is None True
Why is this? Does it have to do with the slightly unorthodox XSL?
Have you tried adding <xsl:output method="text"/> to your xsl?
Actually you should also be using str(xslt_result_doc) instead of etree.tostring(xslt_result_doc).
That was it! Thanks a lot! Martin
participants (2)
-
Laurence Rowe -
Martin Aspeli