how to reassign value to a variable in xslt - xslt-2.0

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.

Related

straUnexpected output xsl:value-of

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>.

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.

Compare Xsl Variable

My Xsl code is like this , I could not enter inside when condition even isFlag is true,
<xsl:variable name="isFlag" select="java:isCustomerUnique($samledata)"/> </xsl:variable>
<xsl:choose>
<xsl:when test="$isFlag = 'true'">
<uniqueData><xsl:value-of select="$uniqueData"/></uniqueData>
<isUnique><xsl:value-of select="$isUnique"/></isUnique>
I could not check the condition if the condition is
<xsl:when test="$isFlag = 'true'">
It is working fine , if I change like this
<xsl:when test="'true'= 'true'">
The conclusion is, that the variable $isFlag is not 'true'.
To debug the document processing just add the following line before xsl:choose to get the actual value of $isFlag:
<xsl:message terminate="no">The value of $isFlag is "<xsl:value-of select="$isFlag"/>"</xsl:message>
To stop the document processing you can set the attribute terminate to yes.

Resources