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.
Related
I have a schematron-file looking like this (as simply as possible)
<sch:pattern id="TDOP_0400">
<sch:rule context="//tekst:Kop">
<xsl:variable name="CONDITION">
<xsl:value-of select="tekst:Label and tekst:Opschrift and tekst:Nummer"/>
</xsl:variable>
</sch:rule>
</sch:pattern>
When I run it in Oxygen, it runs fine, but when I run it from the commandline I get an error.
This is my commandline command:
$ java -cp ../saxon9.9.1.5/saxon9he.jar net.sf.saxon.Transform -t -s:tpod0400.sch -xsl:../saxon9.9.1.5/iso_svrl_for_xslt2.xsl -o:tpod0400.xsl
This is the error message, I get it for every xsl:variable-line:
Warning: unrecognized element xsl:variable
Add "allow-foreign=true" to the command:
$ java -cp ../saxon9.9.1.5/saxon9he.jar net.sf.saxon.Transform -t -s:tpod0400.sch -xsl:../saxon9.9.1.5/iso_svrl_for_xslt2.xsl -o:tpod0400.xsl allow-foreign=true
"allow-foreign" is a parameter in iso_svrl_for_xslt2.xsl, which is documented as follows in the stylesheet:
Pass non-Schematron elements and rich markup to the generated
stylesheet
xsl:variable is a non-Schematron element and is left out unless allow-foreign=true.
Best and most safe practice is to separate sch (schematron) from xslt code. Keep the sch-code inside the rule, and if you need xslt-functionality, break out with a function call to xslt-code, then return the result of the funtion back to the sch-code, and go on with sch-processing.
So short: Never mix up sch and xslt in one programming context, and you will always be safe.
I have an example, never mind what it does or what it is for, it is here to demonstrate how to break out an sch-context to invoke some xslt-code, and then return back to the sch-context:
<sch:pattern id="TPOD_0520">
<sch:rule context="//tekst:Hoofdstuk/tekst:Titel">
<sch:let name="APPLICABLE"
value="$SOORT_REGELING = $OP or $SOORT_REGELING = $OV or $SOORT_REGELING = $WV"/>
<sch:let name="hoofdstuk" value="string(../tekst:Kop/tekst:Nummer)"/>
<sch:let name="titel" value="string(tekst:Titel/tekst:Kop/tekst:Nummer)"/>
<!-- Below is the break-out to XSLT, and the value coming from the function is used in the sch-code -->
<sch:let name="volgorde" value="foo:volgordeTPOD_0520($titel, .)"/>
<sch:let name="CONDITION" value="string-length($volgorde) = 0"/>
<sch:assert test="($APPLICABLE and $CONDITION) or not($APPLICABLE)">
TPOD_0520: Als tussen Hoofdstuk en Afdeling Titel voorkomt dan moet de nummering van Afdelingen beginnen met het samengestelde nummer van de Titel waarin de Afdeling voorkomt, gevolgd door een punt. (betreft hoofdstukken, titels, afdelingen): <xsl:value-of select="$hoofdstuk"/>: <sch:value-of select="$titel"/>: <sch:value-of select="substring($volgorde,1,string-length($volgorde)-2)"/></sch:assert>
</sch:rule>
</sch:pattern>
<xsl:function name="foo:volgordeTPOD_0520">
<xsl:param name="titel" as="xs:string"/>
<xsl:param name="context" as="node()"/>
<xsl:variable name="volgorde">
<xsl:for-each select="$context/tekst:Afdeling">
<xsl:if test="not(string(tekst:Kop/tekst:Nummer)=concat($titel, '.', string(position())))">
<xsl:value-of select="concat(string(tekst:Kop/tekst:Nummer),', ')"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="$volgorde"/>
</xsl:function>
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).
This is my XML
<report>
<format-inputs>
<narrative-entity-ids>
<entity id="28495795" type-cdf-meaning="DIAGNOSES"/>
<entity id="28495741" type-cdf-meaning="DIAGNOSES"/>
<entity id="28495471" type-cdf-meaning="DIAGNOSES"/>
</narrative-entity-ids>
</format-inputs>
</report>
I am creating a function in commonFunction.xslt
<xsl:function name="cdocfx:createEntityIdList" >
<xsl:param name="formatInputsNodes"/>
<xsl:if test="fn:exists(n:report/n:format-inputs)"
<xsl:variable name="entityIdList" as="element()*">
<xsl:for-each select="$formatInputsNodes/n:narrative-entity-ids/n:entity">
<Item><xsl:value-of select="#id"/></Item>
</xsl:for-each>
</xsl:variable>
</xsl:if>
<xsl:copy-of select="$entityIdList"/>
</xsl:function>
I am calling this function in other xslt file where commonFunction.xslt was included
<xsl:variable name="entityIdList" select="cdocfx:createEntityIdList(n:report/n:format-inputs)"/>
</xsl:variable>
My question is variable entityIdList should be value type of element but it is having the document-node type how can i achieve this ??
Please provide minimal but complete samples of XML input, XSLT you have, output you want and the one you get together with any exact error messages you have encountered.
I am currently not sure I understand what you want to achieve, if you construct a variable of type element()* you seem to want to construct a sequence of element nodes. Any xsl:value-of however will only output the string values of the selected items in a text node so it is not clear why you first construct elements if you only want to output string values. If you construct nodes and want to output them use xsl:copy-of or xsl:sequence, not xsl:value-of.
To show two examples of writing a function that returns a sequence of elements (i.e. whose result is of type element()*) I have set up https://xsltfiddle.liberty-development.net/3NzcBtE which has two functions
<xsl:function name="mf:ex1">
<xsl:param name="input" as="element()*"/>
<xsl:for-each select="$input">
<item>{ #id }</item>
</xsl:for-each>
</xsl:function>
<xsl:function name="mf:ex2">
<xsl:param name="input" as="element()*"/>
<xsl:variable name="elements" as="element()*">
<xsl:for-each select="$input">
<item>{ #id }</item>
</xsl:for-each>
</xsl:variable>
<xsl:sequence select="$elements"/>
</xsl:function>
the first simply directly constructs some result elements in the function body, that way the result is a sequence of element nodes. The second function uses your approach of constructing a sequence of elements nodes in a variable, the proper way to return that variable value then from the function is to use xsl:sequence.
It is not clear at which position of the posted code you think are dealing with a document-node() node.
Note also that
<xsl:choose>
<xsl:when test="fn:exists($formatInputsNodes/n:narrative-entity-ids)">
<xsl:for-each select="$formatInputsNodes/n:narrative-entity-ids/n:entity">
<Item><xsl:value-of select="#id"/></Item>
</xsl:for-each>
</xsl:when>
</xsl:choose>
can be simplified to
<xsl:for-each select="$formatInputsNodes/n:narrative-entity-ids/n:entity">
<Item><xsl:value-of select="#id"/></Item>
</xsl:for-each>
As you have now presented an XML input that is at least well-formed and some XSLT snippets (that are unfortunately not well-formed and seem to use a namespace although the XML input shown doesn't use one) here is an attempt to morph that into a working sample
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:cdocfx="http://example.com/cdox-functions"
exclude-result-prefixes="#all"
version="3.0">
<xsl:function name="cdocfx:createEntityIdList" >
<xsl:param name="formatInputsNodes"/>
<xsl:variable name="entityIdList" as="element()*">
<xsl:for-each select="$formatInputsNodes/narrative-entity-ids/entity">
<Item><xsl:value-of select="#id"/></Item>
</xsl:for-each>
</xsl:variable>
<xsl:copy-of select="$entityIdList"/>
</xsl:function>
<xsl:variable name="entityIdList" select="cdocfx:createEntityIdList(report/format-inputs)"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select="$entityIdList instance of element()*, $entityIdList" separator=", "/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/pPqsHTW/1
Output there for the check $entityIdList instance of element()* is true so I am not sure why you say you have a document node.
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>
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.