XPath syntax error thrown when using evaluate() method - xslt-2.0

Still i am getting the below error
Error at xsl:param on line 6 of file:/E:/saxon/parastyleText.xsl:
XPST0003: XPath syntax error at char 0 on line 6 in {...le/#w:val[matches(., c
oncat...}:
Invalid character '^' in expression
Failed to compile stylesheet. 1 error detected.
Modified XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
<xsl:param name="styleName" select="'articletitle'"/>
<xsl:param name="tagName" select="'//w:p[w:pPr/w:pStyle/#w:val[matches(., concat('^(',$styleName,')$'),'i')]]'"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select="saxon:evaluate($tagName)" xmlns:saxon="http://saxon.sf.net/"/><xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Please dont reply that, quotes will make 'tagName' as string and remove those quotes. This value will be actually passed from java as a string , tats y for testing purpose i have passed this xpath as string.

According to the online documentation http://www.saxonica.com/documentation9.1/extensions/functions.html Saxon 9.1 supports an evaluate function in the Saxon namespace http://saxon.sf.net/. So with Saxon 9.1 try <xsl:value-of select="saxon:evaluate($tagName)" xmlns:saxon="http://saxon.sf.net/"/>. Of course you can move the namespace declaration up to the xsl:stylesheet element if you want, I just put it on the xsl:value-of in this post for a short but complete sample of code.
Also note that with your variable named tagName it is likely that you simply have a single element name, in that case it might suffice to use <xsl:value-of select="*[local-name() eq $tagName]"/>.

Related

Exponent or power calculation in saxon9HE

Please suggest how to do math functions like power in XSLT2 with Saxon 9HE.
Getting following error:
Cannot find a matching 2-argument function named {http://exslt.org/math}power()
XML:
<root><num>12.3</num></root>
XSLT 2.0:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:math="http://exslt.org/math"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
extension-element-prefixes="exsl math">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<!--1/(1+e^(-t))--><!-- this is required formula -->
<xsl:template match="num">
<xsl:variable name="varE"><xsl:value-of select="."/></xsl:variable>
<xsl:variable name="varT"><xsl:text>0.718</xsl:text></xsl:variable>
<xsl:variable name="varPower">
<xsl:value-of select="1 div (1 + math:power(number($varE), number(-$varT)))"/>
</xsl:variable>
<xsl:value-of select="$varPower"/>
</xsl:template>
</xsl:stylesheet>
There are XPath standardized math functions like math:pow e.g. math:pow(2, 4) in the namespace https://www.w3.org/2005/xpath-functions/math e.g with the namespace declaration xmlns:math="http://www.w3.org/2005/xpath-functions/math" available in all editions of Saxon (at least with 9.8 but I think it also works with earlier version like 9.7 and 9.6 (documentation http://saxonica.com/html/documentation9.6/functions/math/pow.html says since 9.6 in all editions).

How to convert String to Date YYYY-MM-DD using XSLT 2.0

I need to convert 11/14/2016 - This is String Data Type. I need to convert it to 2016-11-14 using XSLT 2.0. Please let me know how to proceed? I don't want to use subString method. I tried format-date() function from xslt 2.0 but not successful.
You could do something like this. You can use the tokenize function instead, if you do not want to use substring.
Assuming an input XML like:
<string>11/14/2016</string>
When run against a style sheet below:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:variable name="target_string">
<xsl:value-of select="tokenize(string, '/')[last()]"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="tokenize(string, '/')[1]"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="tokenize(string, '/')[2]"/>
</xsl:variable>
<date1>
<xsl:value-of select="xs:date($target_string)"/>
</date1>
<date2>
<xsl:value-of select="format-date(xs:date($target_string), '[MNn] [D], [Y]')"/>
</date2>
</xsl:template>
</xsl:stylesheet>
produces:
<date1>2016-11-14</date1><date2>November 14, 2016</date2>
Sorry to say that XSLT is following ISO 8601 which should be yyyy-mm-dd, so subString will be your only choice.
Reference:
https://www.w3.org/TR/xmlschema-2/#isoformats

Recoverable error while running XSL

XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" exclude-result-prefixes="wp wne w10 w ve o r m v" version="2.0">
<xsl:output method="text"/>
<xsl:param name="styleName"/>
<xsl:template match="w:p">
<xsl:apply-templates/><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="w:r[not
((parent::w:hyperlink[#w:anchor[matches(.,concat('^(',$styleName,')')),'i']]))]">
<xsl:value-of select="replace(., '.', '＀')"/>
</xsl:template>
</xsl:stylesheet>
While processing the above XSL, I am getting the below error,
Recoverable Error:
Recoverable error on line 11
FORG0006: An error occurred matching pattern {w:r[not
((parent::w:hyperlink[#w:anchor[matches(.,concat('^(',$styleName,')')),'i']]))]}:
Effective boolean value is not defined for a sequence of two or more items starting with a boolean
Please Help. I am not able to figure out this.
The problem is with 'i' [modifier added to perform case-insensitive search], It is specified after the matches() method.

How to dynamically fetch value from url in XSLT

I have a url of type C:/Documents and Settings/Saxon/output1/index.html?value=65abc
Now i need to fetch this part from url '65abc' in my xslt. I am getting this value from the previous page when click on a link.
Any idea of how to do it?
Use:
substring-after($pPath, '=')
where $pPath is a reference to the global external xsl:param that contains the value of the url-like) file path, passed from the invoker of the transformation.
In case that pPath contains more than one query-string parameter and you want to access the value of first one, then use:
substring-after(substring-before(substring-after($pPath, '?'), '&'), '=')
If you are using XSLT 2.0 (XPath 2.0), then you can access the value of the the query-string-parameter named $pQName using:
substring-after
(tokenize(substring-after($pPath, '?'), '&')
[starts-with(., concat($pQName, '='))],
'='
)
Here are complete code examples:
The simplest case:
. . .
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pPath" select=
"'C:/Documents and Settings/Saxon/output1/index.html?value=65abc'"/>
<xsl:template match="node()|#*">
<xsl:sequence select="substring-after($pPath, '=')"/>
</xsl:template>
</xsl:stylesheet>
when this is applied on any XML document (not used), the wanted result is produced:
65abc
.2. When this transformation is performed on any XML document (not used):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pPath" select=
"'C:/Documents and Settings/Saxon/output1/index.html?value=65abc&x=1&y=2'"/>
<xsl:param name="pQName" select="'x'"/>
<xsl:template match="node()|#*">
<xsl:sequence select=
"substring-after
(tokenize(substring-after($pPath, '?'), '&')
[starts-with(., concat($pQName, '='))],
'='
)"/>
</xsl:template>
</xsl:stylesheet>
the wanted string (the value for the query-string parameter named x) is produced:
1

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