XSL - Escaping an apostrophe during xsl:when test - xslt

I have the following code which appears to be failing.
<xsl:when test="$trialSiteName = 'Physician&apos;s Office'">
Also, visual studio is complaining saying
"Expected end of expression, found 's"
How am I supposed to escape the character?
XSLT v1.0. Apache XSL-FO processor.

Much more simple -- use:
<xsl:when test="$trialSiteName = "Physician&apos;s Office"">

Declare a variable:
<xsl:variable name="apos" select='"&apos;"'/>
Use the variable like this in the <xsl:when> clause:
<xsl:when test="$trialSiteName = concat('Physician', $apos, 's Office')">

&apos; works for XPath 1.0. If you are using XSLT 2.0 with XPath 2.0 try double apostrophe:
<xsl:when test="$trialSiteName = 'Physician''s Office'">
Look for a full explanation by Dimitre Novatchev in his answer Escape single quote in xslt concat function

in between " you can add what ever special characters you want.
<xsl:when test="$trialSiteName = "Physician's what ever special charactors plainly add Office"">

Related

replace string in xslt 2.0 with replace function

I have a string like this
"My string"
Now I want to replace my with best so that the output will be like best string.
I have tried some thing like this
<xsl:value-of select="replace( 'my string',my,best)"/>
but probably its a wrong syntax
I have googled a lot but found nothing..every where the mechanism to do this XSLT 1.0 is explained.Can any one tell me how to do it in XSLT 2.0 ,The easy way compared to 1.0
Given:
<xsl:variable name="s1" select="'My string'"/>
Simply use:
<xsl:value-of select="replace($s1, 'My', 'best')"/>
Note that a regular expression is applied. Meaning:
<xsl:value-of select="replace('test.replace', '.', ':')"/>
Becomes:
::::::::::::
Be sure to escape the characters that have special meaning to the regular expression interpreter:
<xsl:value-of select="replace('test.replace', '\.', '::')"/>
Becomes:
test::replace
First check, if your xslt processor (saxxon) is the latest release. Then you have to set
<xsl:stylesheet version="2.0" in the head of your xslt-stylesheet. That's it.
Your code was fine, besides you forgot the apostrophs:
<xsl:value-of select="replace( 'my string',my,best)"/>
must be
<xsl:value-of select="replace('my string','my','best')"/>

XSLT- Get substring and pass it as parameters to java function

In the below code snippet, I am trying to get the substring of my #imageMeta node, append some more path location and pass it as a parameter to my java method through XSLT.
<xsl:variable name="imagePathFrom" select="/config/assets/images/{substring-after(#imageMeta,'/')}" />
<xsl:variable name="imagePathTo" select="'/dev/svn_root/platform/system'" />
<xsl:value-of select="filecopy:copyFile($imagePathFrom, $imagePathTo)"/>
My #imageMeta node data looks like Images/common/dialog/dialogue_black.png.
I have to convert the above path to images/common/dialog/dialogue_black.png (note the change of capital 'I' to small 'i') and append some more path data.
So my final path entry should look like "/config/assets/images/common/dialog/dialogue_black.png". When i run my code snippet i get an error stating:
line 51: Error parsing XPath expression '/config/assets/images/{substring-after(#imageMeta,'/')}'.'
Please help.
<xsl:variable name="imagePathFrom" select="/config/assets/images/{substring-after(#imageMeta,'/')}" />
There are two problems here:
A syntax error -- a select is probably the only attribute attribute in XSLT that cannot contain an AVT.
Even without the AVT, this would attempt to select all /config/assets/images nodes, but the intent is that the variable must contain the string "/config/assets/images"
Solution to both problems:
<xsl:variable name="imagePathFrom" select=
"concat('/config/assets/images/', substring-after(#imageMeta,'/')" />
Alternative solution:
<xsl:variable name="imagePathFrom" select=
"concat('/config/assets/',
translate(substring(#imageMeta, 1, 1),
$vUpper,
$vLower
),
substring(#imageMeta, 2)
)" />
where $vLower and $vUpper are defined, respectively, as:
'abcdefghijklmnopqrstuvwxyz'
and
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
There is one problem in your code:
<xsl:variable name="imagePathFrom" select="/config/assets/images/{substring-after(#imageMeta,'/')}" />
It suppose to be ..
<xsl:variable name="imagePathFrom" select="substring-after(/config/assets/images/#imageMeta,'/')" />
infant programmer 'Aravind' suggestion will solve your parse error.
You also mentioned you wanted to lower-case the capital i. Two options here:
Using XSLT 1.0, this StackOverflow answer explains how to lower-case the first character of a string. It won't work for Unicode characters such as 'Í' but you probably don't need it.
XSLT 2.0 has a lower-case function, which will lower-case your entire string, and may not be what you're looking for.

xsl: how to use parameter inside "match"?

My xsl has a parameter
<xsl:param name="halfPath" select="'halfPath'"/>
I want to use it inside match
<xsl:template match="Element[#at1='value1' and not(#at2='{$halfPath}/another/half/of/the/path')]"/>
But this doesn't work. I guess a can not use parameters inside ''. How to fix/workaround that?
The XSLT 1.0 W3C Specification forbids referencing variables/parameters inside a match pattern.:
"It is an error for the value of the
match attribute to contain a
VariableReference"
There is no such limitation in XSLT 2.0, so use XSLT 2.0.
If due to unsurmountable reasons using XSLT2.0 isn't possible, put the complete body of the <xsl:template> instruction inside an <xsl:if> where the test in conjunction with the match pattern is equivalent to the XSLT 2.0 match pattern that contains the variable/parameter reference(s).
In a more complicated case where you have more than one template matching the same kind of node but with different predicates that reference variables/parameters, then a wrapping <xsl:choose> will need to be used instead of a wrapping <xsl:if>.
Well, you could use a conditional instruction inside the template:
<xsl:template match="Element[#at1='value1']">
<xsl:if test="not(#at2=concat($halfPath,'/another/half/of/the/path'))">
.. do something
</xsl:if>
</xsl:template>
You just need to be aware that this template will handle all elements that satisfy the first condition. If you have a different template that handles elements that match the first, but not the second, then use an <xsl:choose>, and put the other template's body in the <xsl:otherwise> block.
Or, XSLT2 can handle it as is if you can switch to an XSLT2 processor.
This topic had the answer to my question, but the proposed solution by Flynn1179 was not quite correct for me (YMMV). So try it the way it is suggested by people more expert than me, but if it doesn't work for you, consider how I solved it. I am using xsltproc that only handles XSL version 1.0.
I needed to match <leadTime hour="0024">, but use a param: <xsl:param name="hour">0024</xsl:param>. I found that:
<xsl:if test="#hour='{$hour}'"> did not work, despite statements here and elsewhere that this is the required syntax for XSL v.1.0.
Instead, the simpler <xsl:if test="#hour=$hour"> did the job.
One other point: it is suggested above by Dimitre that you put template inside if statement. xsltproc complained about this: instead I put the if statement inside the template:
<xsl:template match="leadTime">
<xsl:if test="#hour=$leadhour">
<xsl:copy>
<xsl:apply-templates select="node() | #*"/>
</xsl:copy>
</xsl:if>
</xsl:template>
In XSLT 2.0 you can refer to global variables within a match pattern, but the syntax is simpler than your guess:
<xsl:template match="Element[#at1='value1' and
not(#at2=$halfPath/another/half/of/the/path)]"/>
rather than
<xsl:template match="Element[#at1='value1' and
not(#at2='{$halfPath}/another/half/of/the/path')]"/>
Also, the semantics are not what you appear to be expecting: a variable referenced on the lhs of "/" must contain a node-set, not a fragment of an XPath expression.

Concatenate with escaped chars in xslt?

I'm writing xslt code which concatenates some string:
<xsl:attribute name='src'>
<xsl:value-of select="concat('url(&apos;', $imgSrc, '&apos;)')" />
</xsl:attribute>
For some reason I can't use it, I keep getting this error:
Unknown function - Name and number of arguments do not match any function signature in the static context - 'http://www.w3.org/2005/xpath-functions:concat'
while evaluating the expression:
select="concat('url(&apos;', $imgSrc, '&apos;)')"
Any idea?
thx
====================
EDIT
I'm trying to get:
url('some_path')
Was having trouble with the apostrophes, but now it just doesn't work.
The &apos; references are resolved by the XML parser that parses your XSLT. Your XSLT processor never sees them. What your XSLT processor sees is:
concat('url('', $imgSrc, '')')
Which is not valid because the commas don't end up in the right place to separate the arguments. However, this might work for you, depending on the serializer your XSLT processor uses:
concat("url('", $imgSrc, "')")
This surrounds the arguments in double-quotes, so that your single-quotes do not conflict. The XSLT processor should see this:
concat("url('", $imgSrc, "')")
Another option is to define a variable:
<xsl:variable name="apos" select='"&apos;"'/>
Which can be used like this:
concat('url(', $apos, $imgSrc, $apos, ')')
More here:
When you apply an XSLT stylesheet to a
document, if entities are declared and
referenced in that document, your XSLT
processor won't even know about them.
An XSLT processor leaves the job of
parsing the input document (reading it
and figuring out what's what) to an
XML parser; that's why the
installation of some XSLT processors
requires you to identify the XML
parser you want them to use. (Others
include an XML parser as part of their
installation.) An important part of an
XML parser's job is to resolve all
entity references, so that if the
input document's DTD declares a cpdate
entity as having the value "2001" and
the document has the line "copyright
&cpdate; all rights reserved", the XML
parser will pass along the text node
"copyright 2001 all rights reserved"
to put on the XSLT source tree.
From http://www.w3.org/TR/xpath/#NT-Literal
[29] Literal ::= '"' [^"]* '"' | "'" [^']* "'"
Meaning that an XPath literal string value can't have the delimiter as also part of the content.
For this you should use the host language. In XSLT:
<xsl:variable name="$vPrefix">url('</xsl:variable>
<xsl:variable name="$vSufix">')</xsl:variable>
<xsl:attribute name="src">
<xsl:value-of select="concat($vPrefix, $imgSrc, $vSufix)" />
</xsl:attribute>
Or more proper:
<xsl:attribute name="src">
<xsl:text>url('</xsl:text>
<xsl:value-of select="$imgSrc"/>
<xsl:text>')</xsl:text>
</xsl:attribute>

XSL - Invalid Xpath Extension on Replace

Im getting on error when I try and use the following:
<xsl:variable name="url" select="guid"/>
<xsl:variable name="vid" select="substring-after($url,'podcast/')"/>
<xsl:variable name="pre" select="substring-before($vid,'.mp4')"/>
<<xsl:variable name="p" select="replace($pre,'_','-')"/>
<xsl:variable name="p1" select="concat($p,'.embed_thumbnail.jpg')"/>
<xsl:variable name="p2" select="concat('http://images.ted.com/images/ted/tedindex/embed-posters/',$p1)"/>
Can anyone see a problem, it all looks good to me?
Are you using an XSLT 1 processor? The replace function appeared in XPath 2.0 and is therefore not available in XSLT 1.
In this case you could just use the translate function instead.
You have an extra unescaped less-than sign before your p variable's definition:
<<xsl:variable name="p" select="replace($pre,'_','-')"/>
That's not valid syntax.
You should either remove it:
<xsl:variable name="p" select="replace($pre,'_','-')"/>
Or escape it:
<<xsl:variable name="p" select="replace($pre,'_','-')"/>
I see a '<<' at the start of line 4, is that it?