straUnexpected output xsl:value-of - xslt-2.0

Havin a strange issue again. I am tryinodo a simple value- of of field CRETIM:
<CREDAT>20220628</CREDAT>
<CRETIM>112159</CRETIM>
<xsl:attribute name="timestamp">
<xsl:value-of select="EDI_DC40/CRETIM" disable-output-escaping="yes"/>
a
</xsl:attribute>
Output looks as follows:
First6 characterrs are ok, but no idea what happened to th rest.Any idea whats wrong here and how this can be fixed?
Thank you!

If that is XSLT 2 I wonder why you don't use the select attribute on xsl:attribute e.g. <xsl:attribute name="timestamp" select="EDI_DC40/CRETIM"/>.
If you use xsl:value-of wrapped into xsl:attribute make sure you have stray data (like that a letter) inside of xsl:attribute. If the sole a letter is intentional then use e.g. <xsl:attribute name="timestamp" select="concat(EDI_DC40/CRETIM, 'a')"/> or <xsl:attribute name="timestamp"><xsl:value-of select="EDI_DC40/CRETIM"/>a</xsl:attribute>.

Related

Conditional Formatting XSL

I'm trying to make <sup> elements superscripted when I encounter them. I'm iterating over a large file which I can include if required, basically <xml><article><body><p><em></em><sup></sup></p></body></article></xml>
I'm receiving:
Error reported by XML parser: The element type "fo:inline" must be terminated by
the matching end-tag "</fo:inline>"
when trying to use the below to raise the superscripts:
<xsl:for-each select="*">
<fo:block>
<xsl:if test="name() = 'sup'">
<fo:inline vertical-align='super' baseline-shift='4pt'>
</xsl:if>
<xsl:apply-templates select="." mode="xhtml"/>
<xsl:if test="name() = 'sup'">
</fo:inline>
</xsl:if>
</fo:block>
</xsl:for-each>
How can I correct this so the vertical-align='super' is only for sup elements; and is there a better approach to this? I plan to do the same for ems later.
My code which I use currently but puts everything out as plain text is:
<xsl:for-each select="*">
<fo:block><xsl:apply-templates select="." mode="xhtml"/></fo:block>
</xsl:for-each>
If you want to transform <sup></sup> to <fo:inline vertical-align='super' baseline-shift='4pt'></fo:inline> then the usual way with XSLT is to set up a template
<xsl:template match="sup">
<fo:inline vertical-align='super' baseline-shift='4pt'>
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
I am not sure whether you want to do that in general or for a particular mode (in that case add mode="mode-name" on the xsl:template and mode="#current" on the xsl:apply-templates).

how to match the case sensitive characters in elements

I want to match the two or more case-sensitive characters in element of familName in author element. If found the ERROR message should be shown otherwise the familyName content will shown. The below code is not viewed in browser. Please check. I have used the xsl version is 2.0.
XML CODE
<author><familyName>CH</familyName> <givenNames>JC</givenNames></author>
XSLT CODE
<xsl:for-each select="author">
<xsl:choose>
<xsl:when test="matches(familyName,'([A-Z]){{1,}}')"><xsl:text>ERROR</xsl:text></xsl:when>
<xsl:otherwise>
<xsl:value-of select="familyName"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
Its working for me. You can write a specific template for showing error:
<xsl:template match="familyName[matches(.,'^[A-Z][A-Z]+')]">
<xsl:text>ERROR</xsl:text>
</xsl:template>

pattern not matching though declared

I've the below XML.
<root>
<para>
<label>5.</label> In essence, the Court in <star.page>19</star.page>
</para>
<para>
<label><star.page>21</star.page> 13.</label> Frankly, I cannot see how
one can escape
</para>
</root>
and using the below XSLT.
<xsl:template match="para">
<xsl:apply-templates select="./node()[1][self::star.page]|./label/node()[1][self::star.page]" mode="first"/>
</xsl:template>
<xsl:template match="star.page" mode="first">
<xsl:if test="preceding::star.page">
<xsl:processing-instruction name="pb">
<xsl:text>label='</xsl:text>
<xsl:value-of select="."/>
<xsl:text>'</xsl:text>
<xsl:text>?</xsl:text>
</xsl:processing-instruction>
<a name="{concat('pg_',.)}"/>
</xsl:if>
</xsl:template>
here when i try to run this code, the first para star.page is getting caught, but the second star.page, i.e. <para><label><star.page>21</star.page> 13.</label>... is not getting caught. please let me know where am i going wrong. here i'm taking [1], since i want to catch the first occurance.
Thanks
I just tried your code on xmlplayground, both the star.page elements reach the template but the if clause is preventing the first from reaching the output.

how to reassign value to a variable in xslt

Here I am trying to run a single loop that searches entire xml and depending on the various conditions different variable get different values . so that it can be used later for reference.
Sample code :
<xsl:for-each select='root'>
<xsl:choose>
<xsl:when test='first'>
<xsl:variable name='first' select='root/first' />
</xsl:when>
<xsl:when test='second'>
<xsl:variable name='namew' select='root/second' />
</xsl:when>
<xsl:otherwise>
<xsl:variable name='other'>unknown</xsl:variable>
</xsl:otherwise>
</xsl:choose>
I Know it wont work here and i also know the reason (variable scope and constant behavior of variable) , actually i want to know the alternative solution to this problem.
XSLT is a functional language.
Among many things, this means that the value of a variable, once defined, cannot be changed.
If you specify a particular problem that you want to solve, many of us will be able to give you a solution in which variable's values aren't changed.

What is the ROUND function behavior in Orbeon Forms?

In Orbeon Forms (dev-post-3.7.1.200911140400) we have code in an XPL that do some calculation, and part of this calculation is we ROUND the result to 2 decimal places. Below is an example of the code we use to do the calculation:
<xsl:when test="$total_c_w != 0">
<gpa><xsl:value-of select="(round(($total_p_c_w div $total_c_w) * 100) div 100)"/></gpa>
</xsl:when>
According to the standard XPATH documentation on the ROUND function; Rounds a numeric value to the nearest whole number, rounding x.5 towards positive infinity.
But we encounter a case where the ROUND function is rounding 237.5 to 237, instead of 238. This is just an example, there are other cases where a similar problem involving x.5 is happening.
For example mention, the values in the calculation are:
$total_p_c_w = 7.6, $total_c_w = 3.2
=====================================================
Alex,
Thanks for the guidance. I did some more debugging and found something weird please refer to the following XSL code that I tested with on the latest Orbeon Forms 3.9.0.201105152046 CE.
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:template match="/">
<main>
<xsl:variable name="tppcw" select="/root/studentpcw/total_p_c_w" as="xs:double"/>
<xsl:variable name="tccw" select="/root/studentpcw/total_c_w" as="xs:double"/>
<xsl:variable name="tpcw" select="sum(/root/studentpcw/total_p_c_w)"/>
<xsl:variable name="tcw" select="sum(/root/studentpcw/total_c_w)"/>
<xsl:variable name="total_p_c_w" select="7.6"/>
<xsl:variable name="total_c_w" select="3.2"/>
<var1><xsl:value-of select="sum(/root/studentpcw/total_p_c_w)"/></var1>
<var2><xsl:value-of select="sum(/root/studentpcw/total_c_w)"/></var2>
<var3><xsl:value-of select="$total_p_c_w"/></var3>
<var4><xsl:value-of select="$total_c_w"/></var4>
<result1>
<xsl:value-of select="round(($total_p_c_w div $total_c_w) * 100)"/>
</result1>
<result2>
<xsl:value-of select="round(($tppcw div $tccw) * 100)"/>
</result2>
</main>
</xsl:template>
</xsl:transform>
Apply the above code at this sample document:
<root>
<studentpcw>
<total_p_c_w>7.6</total_p_c_w>
<total_c_w>3.2</total_c_w>
</studentpcw>
</root>
The result is quite unexpected;
<main xmlns:xs="http://www.w3.org/2001/XMLSchema">
<var1>7.6</var1>
<var2>3.2</var2>
<var3>7.6</var3>
<var4>3.2</var4>
<result1>238</result1>
<result2>237</result2>
</main>
The problem is that if I assign a literal number to the variable and use that variable in the rounding function, the result is as I expected. If I select the value from a node and assign to the variable and use that variable in the rounding function, the result is wrong or unexpected.
I get a result of 238 running the following stylesheet in a nightly build through the XSLT sandbox (which, if you have Orbeon Forms installed locally, you can access through http://localhost:8080/orbeon/sandbox-transformations/xslt/).
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:template match="/">
<result>
<xsl:variable name="total_p_c_w" select="7.6"/>
<xsl:variable name="total_c_w" select="3.2"/>
<xsl:value-of select="round(($total_p_c_w div $total_c_w) * 100)"/>
</result>
</xsl:template>
</xsl:transform>
I believe this is the result you expected, but that you might be getting something different with the version you are using. Could you try the above example in the XSLT sandbox of the version you are using? If you're getting 237 instead of 238, then this is a sign that this issue has been fixed, and I would then recommend you to upgrade to a newer version of Orbeon Forms (currently 3.9).
(Note that this is most likely not something in Orbeon Forms per se, but in the XSLT implementation Orbeon Forms uses, which is the excellent Saxon.)

Resources