Reputation: 3722
I have an XML file to render with XSLT 1.0.
My cas is the following :
If value of
longName
is "Oui_Combi"
$Publication
=prodDate
value (21.11.2018)else
$Publication
=productionDates
value (17.11.2018, 21.11.2018)
I'm not sur my syntax is correct on the for-each and/or on the xsl-if
XML file :
<?xml version="1.0" encoding="UTF-8"?>
<Manuscript dateAndTime="2018-11-16T10:20:59.177+01:00" renderEPS="" forMediation="false">
<Order>
<OrderHeader productionDates="17.11.2018, 21.11.2018">
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<Criterion name="TypePublicity" ordering="1">
TypePubOccasionnel <ValueParameter longName="Occasionnel"/>
</Criterion>
<Criterion name="JuraCombi" ordering="2">
Oui_Combi <ValueParameter longName="Oui_Combi"/>
^^^^^^^^^^^^^^^^^^^^
</Criterion>
</OrderHeader>
<FirstIssueData prodDate="21.11.2018"></FirstIssueData>
</Order> ^^^^^^^^^^^^^^^^^^^^^
</Manuscript>
XSL part where I create my variable :
<xsl:for-each select="Order/OrderHeader/Criterion">
<xsl:if test="@name = 'JuraCombi'">
<xsl:if test="ValueParameter/@longName = 'Oui_Combi'">
<xsl:variable name="JuraCombi">
OUI
</xsl:variable>
<xsl:variable name="Publication">
<xsl:value-of select="/Order/FirstIssueData/@prodDate" />
</xsl:variable>
</xsl:if>
<xsl:if test="ValueParameter/@longName != 'Oui_Combi'">
<xsl:variable name="JuraCombi">
NON
</xsl:variable>
<xsl:variable name="Publication">
<xsl:value-of select="/Order/OrderHeader/@productionDates" />
</xsl:variable>
</xsl:if>
</xsl:if>
</xsl:for-each>
...
The XSL part where I want to print my variable $Publication
:
<xsl:template match="OrderHeader">
<fo:table
table-layout="fixed"
width="18cm"
font-size="10pt"
padding="1.0pt">
<fo:table-column column-width="30mm"/>
<fo:table-column column-width="60mm"/>
<fo:table-column column-width="30mm"/>
<fo:table-column column-width="60mm"/>
<fo:table-body>
...
<fo:table-row>
<fo:table-cell>
<fo:block padding="0.5cm">
Parutions
</fo:block>
</fo:table-cell>
<fo:table-cell number-columns-spanned="3">
<fo:block padding="0.5cm">
<xsl:copy-of select="$Publication" />
</fo:block> ^^^^^^^^^^^^
</fo:table-cell>
</fo:table-row>
...
</fo:table-body>
</fo:table>
</xsl:template>
Maybe we can achieve it without for-each?
Not any online XSLT tool/checker can get me the detailled error but the rendering stops!
Thanks for help
Upvotes: 1
Views: 3305
Reputation: 8068
The scope of an XSLT variable is limited to the element that contains the xsl:variable
and it applies only to expressions that occur after the xsl:variable
. I.e., "the binding is visible for all following siblings and their descendants" as it says in the XSLT 1.0 spec (see https://www.w3.org/TR/1999/REC-xslt-19991116#local-variables).
So your variables are out of scope outside of the xsl:if
in which they are declared.
The thing to do is to turn your logic inside-out and put the conditional logic inside each xsl:variable
element. Something like (untested):
<xsl:variable name="JuraCombi">
<xsl:choose>
<xsl:when test="ValueParameter/@longName = 'Oui_Combi'">OUI</xsl:when>
<xsl:otherwise>NON</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="Publication">
<xsl:choose>
<xsl:when test="ValueParameter/@longName = 'Oui_Combi'">
<xsl:value-of select="/Manuscript/Order/FirstIssueData/@prodDate" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="../@productionDates" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Note that your XPath to select @prodDate
would not select anything. It needs the /Manuscript
step because Manuscript
is the document element.
It's not clear how your code for declaring the variables relates to the template that creates the fo:table
. For the variable values to be able to apply, you'd need to have the xsl:apply-templates
that selects OrderHeader
to be within the scope of the variables' declarations, and you'd need to pass the variables' values to the template using xsl:with-param
and xsl:param
. See https://www.w3.org/TR/1999/REC-xslt-19991116#section-Passing-Parameters-to-Templates.
I'm not sure that I know what you mean in your comment, so this is the best solution that I can intuit:
<xsl:template match="Order">
<xsl:variable name="JuraCombi">
<xsl:choose>
<xsl:when test="OrderHeader/Criterion[@name = 'JuraCombi']/ValueParameter/@longName = 'Oui_Combi'">OUI</xsl:when>
<xsl:otherwise>NON</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="Publication">
<xsl:choose>
<xsl:when test="$JuraCombi = 'OUI'">
<xsl:value-of select="FirstIssueData/@prodDate" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="OrderHeader/@productionDates" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:table
table-layout="fixed"
width="18cm"
font-size="10pt"
padding="1.0pt">
<fo:table-column column-width="30mm"/>
<fo:table-column column-width="60mm"/>
<fo:table-column column-width="30mm"/>
<fo:table-column column-width="60mm"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block padding="0.5cm">
Parutions
</fo:block>
</fo:table-cell>
<fo:table-cell number-columns-spanned="3">
<fo:block padding="0.5cm">
<xsl:copy-of select="$Publication" />
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</xsl:template>
Upvotes: 1