use a xslt variable to define table padding - html

I would like to declare a variable in my xslt file that is styling my xml. I intend to use the variable to pad the tableview cells. depending on what data is being read will depend how far the padding is from the left of the table.
So I was wondering if its possible to then use this padding1 var on tablecell? This is currently how I am attempting this idea, with not much success mind you as when I now load the xml I am getting a blank screen.
Anyway this is my code
<xsl:variable name="padding1" select="15"/>
<td style="padding-left: padding1;" colspan="2" bgcolor="#C0C0C0">
In the above code I am declaring a variable named padding1 and passing it the value 15, I would then like to use it on padding-left much like you would with a 15px type value.

You can use an AVT to reference your variable:
<td style="padding-left: {$padding1}px;" colspan="2" bgcolor="#C0C0C0">...</td>

You should probably include the unit in your variable. You can even do math operations with the unit intact:
<xsl:variable name="content-width">180mm</xsl:variable>
...
<fo:table-column column-width="{$content-width}*0.5"/>

Related

Is there a way to have an Xquery in an XSLT stylesheet which will be executed upon transformation?

I have an XML file which I've been trying to transform both with xQuery and XSLT at the same moment.
The document basically encodes two different types of text according to TEI standards. The first part is a philological study which I have written about an epic poem, and the second part is a scholarly edition of said poem.
<text>
<front><!-- chapters of the study --></front>
<body>
<lg n="1">
<l n="1.a">first line of the poem</l>
<l n="1.a">second line with <distinct>interesting stuff</distinct></l></lg>
<!-- rest of the poem-->
</body></text>
My main goal is to transform this with XSLT into a nicely formatted html document, and for the most part it works.
Now, the study discusses data from the edition ("This interesting stuff occurs quite often in our poem, as is shown in the following table"). Since all the "interesting stuff" is marked up (see example above), I can easily create those tables using a combination of HTML and xQuery:
<table>
<tr>
<td>Verse Number</td>
<td>Interesting Stuff</td>
<tr>
for $case in doc("mydocument.xml")//distinct
return
<tr>
<td>{data($case/ancestor::l/#n)}</td>
<td>$case</td></tr></table>
The easy way at the moment would be to change the xQuery so it will create a TEI-conform xml table and copy that manually into the document. Then, the XSLT will work smoothly, just as it does for the few static tables that I have. But most of my tables should be dynamic, I want the numbers to change if I change something in the edition. This should be done every time a new reader opens the formatted text in the browser (i.e., each time the XSLT transformation is executed).
I tried combining the code as follows:
<xsl:template match="table[type='query']">
{ (: the xQuery-html instructions from above go here :) }
</xsl template>
I creates a table at the right place, but before it and in the cells it just repeats the xQuery instructions. I've been looking for similar questions, but I found only the reverse process, i.e. how to use xQuery to create XSLT (for example this: calling XQuery from XSLT, building XSLT dynamically in XQuery?), which does not help my problem.
Is there a way to combine the two codes?
Thanks in advance for your help!
There are various ways you can combine XSLT and XQuery. You can have XSLT tasks and XQuery tasks in the same pipeline, or you can invoke XQuery functions from XSLT (for example using load-xquery-module() in XSLT 3.0). But for the case you're describing, it's simplest to just replace the FLWOR expression with an equivalent xsl:for each:
<xsl:for-each select='doc("mydocument.xml")//distinct'>
<xsl:variable name="case" select="."/>
<tr>
<td>{$case/ancestor::l/#n}</td>
<td>{$case}</td>
</tr>
</xsl:for-each>
Note: XSLT 3.0 allows the curly-brace syntax (you need to specify expand-text="yes") but the semantics are slightly different from XQuery - it means "value-of" rather than "copy-of".

StringTemplate: HTML row formatting (odd/even)

I am new to StringTemplate template engine and want to use it for generating an html document with a table. I want to alter the style of the table rows depending on whether it is odd or even. I found a discussion on the stringtemplate-interest mailing list that describes the general approach ([stringtemplate-interest] Odd even row formatting).
But I have an additional requirement which breaks this general approach (I think). I want to render rows depending on the existence of a value. So I am working with a conditional expression $if(expr)$. My template looks like this.
delimiters „$“,“$“
htmlTable(valueA, valueB, valueC, valueD) ::= <<
<table>
<tr styleClass='odd'><td>$valueA$</td></tr>
$if(valueB)$
<tr><td>$valueB$</td></tr>
$endif$
<tr styleClass='odd'><td>$valueC$</td></tr>
<tr><td>$valueD$</td></tr>
</table>
>>
In the given template I can not use the hard coded styleClass attribute, because it would render the table wrong if the valueB parameter does not exist.
Is my requirement realizable with a template engine like StringTemplate, which focus on separation of model and view? Or is there too much model in the requirement as to implement it in the view? I know how to do it in other template engines (i. e. FreeMarker or Apache Velocity) or I might use some fancy CSS or javascript stuff but I would rather keep the model-view separation and use StringTemplates internal instruments.

Special Characters in HTML Element

What I'm trying to do is output a percent sign (%) directly into a < td > tag. Below is my code:
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="item_container" %%=v(#Item_Container_Style)=%%>
...
When I test the XSL I get the following error:
SAXParseException: Expected an attribute name (Set_A_Custom.xsl, line 205, column 38)
So basically it's seeing "%%=v(#Item_Container_Style)=%%" as invalid HTML but I need this code to be there.
If you are wondering why I am doing this it is because I am writing the XSL to output HTML that contains AMPscript (An ExactTarget proprietary Scripting language). You don't need to know anything about AMPscript though to help me out though, I just need to output the percent sign (%) in the HTML and everything will work.
Any ideas? For the record I'm using XSL 1.0. Thanks all!
An XSLT stylesheet must itself be well-formed XML, so you can't include this kind of construct directly in the stylesheet. If the XSLT processor you're using supports disable-output-escaping then you would be able to do something like
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<xsl:text disable-output-escaping="yes"><![CDATA[<td class="item_container" %%=v(#Item_Container_Style)=%%>]]></xsl:text>
...
<xsl:text disable-output-escaping="yes"><![CDATA[</td>]]></xsl:text>
</tr>
</table>
If it does not allow disable-output-escaping then your only option is to use the text output method, and write all the tags you want to output as text with the angle brackets escaped (or in CDATA).
What I'm trying to do is output a percent sign (%) directly into a <td> tag.
Not possible with the "html" or "xml" output modes. XSLT has been designed to create syntactically sane HTML, you cannot make it do anything else.
Of course you could switch to the "text" output mode and do whatever you like, but generating HTML this way it a lot harder.
Alternatively you can use disable-output-escaping, if your XSLT processor supports it, but this will quickly degenerate your XSLT stylesheet into a mess if you need to do it in many places.
That being said, here's a proposal. In XSLT you use the "html" output mode and this:
<td
class="item_container"
amp-1="%%=v({#Item_Container_Style})%%"
amp-2="%%=v({#Some_Other_Element})%%"
>
some text %%=v(<xsl:value-of select="Other_Stuff" />)%% more text
</td>
That is syntactically valid XSLT which covers both cases (multiple placeholders in attributes, multiple placeholders in the text) and creates syntactically valid HTML:
<td
class="item_container"
amp-1="%%=v(item container style content)%%"
amp-2="%%=v(some other element content)%%"
>
Here some text %%=v(other stuff)%%
</td>
and then you use a post-processing step to convert that HTML into AMPscript:
Regex-replace \bamp-\d+="(%%[\s\S]*?%%)" with $1, which would result in
<td
class="item_container"
%%=v(item container style content)%%
%%=v(some other element content)%%
>
Here some text %%=v(other stuff)%%
</td>
Handling HTML with regular expressions is generally strongly dis-recommended, but this might just be a narrow-enough use case.
AMPScript appears to have a standards-based syntax as an alternative to its proprietary syntax:
Delimiter Comparison
The table below demonstrates the similarities between standard AMPscript delimiters and server-side delimiters.
Standard AMPscript Delimiter Tag-based AMPscript Delimiter
%%[ <script runat=server language=ampscript>
etc
Does this help you?

Can I use knitr to apply CSS styles to individual table cells?

Is it possible to apply a class attribute to individual table cells using knitr? I have successfully applied a class attribute to the section heading that contains a knitr::kable generated table and used that to format the entire table. However, I would like to be able to conditionally format individual cells which would require being able to apply a class to specific <td> elements.
My current workaround is to programmatically wrap the cell contents in a pair of <span> tags and pass that on to knitr::kable. This approach only allows me to format the text inside the cell versus the entire cell (e.g. setting the cell background color). Here's an example of what I'm currently using:
## Read in the report, process the data, send to kable
rpt <- generate.report()
mutate(rpt, Col2 = ifelse(abs(Col2) > Threshold,
paste('<span class="warning">',
sprintf("%.2f", Col2), '</span>'),
sprintf("%.2f", Col2))) %>%
knitr::kable(format="markdown", align = c("l", rep("r", 4)),
col.names = gsub("\\.", "<br>", colnames(.)))
Which results in the following example HTML output:
<td align="right"><span class="warning"> -1.74 </span></td>
I would like to be able to have knitr::kable generate something like this:
<td align="right" class="warning"> -1.74 </td>
That way I could apply css styles to the <td> tag vice the <span> tag.
package ReporteRs may help. Have a look here FlexTable.
You can then get the corresponding HTML code with function as.html and reuse it within your knitr code.
Ok, this may not be the answer but it may point you in the right direction. I had a similar problem formatting individual cells in knitr to prepare a pdf. In the end, I use xtable and wrote a function that relied on a logical matrix to decide whether or not a cell in the output table would be formatted.
I couldn't quite get it to work smoothly by myself so I had to post it on here and with the help of ivyleavedtoadflax I was able to develop a reasonably easy to use function to apply formatting to certain cells in an xtable in knitr.
Here's the link to my post
As I say, it's not the exact solution to your problem but it may point you in the right direction.

Parsing through text with incorrect attribute definition

While trying to parse an html document as XML (added xml start at the beginning) I've ran into a problem with attribute inside tags.
<tr>
<td class="yfnc_tabledata1" nowrap align="right">Jun 4, 2013</td>
<td class="yfnc_tabledata1" align="right">453.22</td>
<td class="yfnc_tabledata1" align="right">454.43</td>
<td class="yfnc_tabledata1" align="right">447.39</td>
<td class="yfnc_tabledata1" align="right">449.31</td>
<td class="yfnc_tabledata1" align="right">10,454,600</td>
<td class="yfnc_tabledata1" align="right">449.31</td>
</tr>
While normally it wouldn't matter (since my xslt code doesn't actually reference it), I am getting an error :
ERROR: 'Attribute name "nowrap" associated with an element type "td" must be followed by the ' = ' character.'
ERROR: 'com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Attribute name "nowrap" associated with an element type "td" must be followed by the ' = ' character.'
So i was wondering if there's a way to make it suppress / ignore those errors. (Looking for a way of doing it that doesn't involve a separate parse through that would remove all nowrap first.)
(For reference, xml : http://pastebin.com/TLD4bZkq , xslt : http://pastebin.com/dPzDzeAX )
The data you're trying to process isn't XML, so the XML parser is right to produce an error.
Depending on what XSLT processor you're using and how you call it you might be able to use an HTML parser instead of an XML parser to parse your HTML into a DOM tree which you then pass to the XSLT processor, rather than having the processor parse the file itself.
But remember that XSLT expects namespace-well-formed XML and if the parser's output doesn't conform to this then you will have problems. For example, in Java (which is what I'm most familiar with), for a DOM Document to be usable by XSLT it must have been produced by a namespace-aware parser even if the document in question doesn't actually use any namespaces.