Subject: Re: [xsl] xsl:if test = empty string, returns true From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx> Date: Sun, 13 May 2012 16:24:37 -0400 |
According to http://www.w3.org/TR/xpath/#section-Boolean-Functions:select="document(iri-to-uri($PLIST))"/>
> The boolean function converts [] a string to true if and only if its length is non-zero.
My XSLT 2.0 stylesheet has an xsl:if element testing a function that seems to be returning a string of length zero, and yet the test evaluates to true. I am processing the stylesheet with Saxon-HE 9.2.1.2J with this command line:
> java -jar saxon/saxon9he.jar -it:main -xsl:./test.xsl
This is the stylesheet `test.xsl`:
> <?xml version="1.0" encoding="UTF-8"?> > <xsl:stylesheet version="2.0" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > xmlns:me="null"> > > <xsl:variable name="PLIST" select="'./test.plist'"/> > > <!-- Load external plist into variable --> > <xsl:variable name="metadata"
> > <!-- Function to fetch value of a key-string pair in plist --> > <xsl:function name="me:metadata">
Not having added an as= constraint, you are creating a temporary tree with a text node child.
> <xsl:param name="label"/> > <xsl:value-of
select="normalize-space($metadata/plist/dict/key[text()=$label]/following::no de()[1]/text())"/>
Note that the following:: axis looks all the way to the end of the document. And, you are looking for the adjacent node (which in your example is a text node), rather than the adjacent element (unless you are invoking saxon with the option to strip white-space text nodes from your input, in which case that is not true). So I suggest using following-sibling::* in case you do end up with white-space text nodes.
BTW, I very rarely ever have to address text() nodes and the above would be better written as:
<xsl:value-of select="normalize-space($metadata/plist/dict/key[.=$label]/following-sibling: :*[1])"/>
This is not just a matter of style ... consider how your code would not work when there is more than one text node:
> </xsl:function> > > <xsl:output method="text" encoding="UTF-8"/> > > <xsl:template name="main" exclude-result-prefixes="me">
> <xsl:choose> > <xsl:when test="me:metadata('testkey')"> > testkey = "<xsl:value-of select="me:metadata('testkey')"/>" > testkey's length = <xsl:value-of select="string-length(me:metadata('testkey'))"/> > </xsl:when> > <xsl:otherwise> > "testkey" is empty or does not exist. > </xsl:otherwise> > </xsl:choose> > </xsl:template> > > </xsl:stylesheet> ... Any idea why the test evaluates to true?
Because the returned data type of the function value is a temporary tree and while it may or may not have a text node child, the document node in the tree makes the test true().
Please note that I am not wondering whether the way I wrote the stylesheet is the most appropriate way to do what it is supposed to do, but why the test is evaluating to true.
Nevertheless I hope the additional comments are considered helpful and not critical. I wouldn't want readers of the archive to use text() as you are.
-- Public XSLT, XSL-FO, UBL and code list classes in Europe -- Oct 2012 Contact us for world-wide XML consulting and instructor-led training Free 5-hour lecture: http://www.CraneSoftwrights.com/links/udemy.htm Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Google+ profile: https://plus.google.com/116832879756988317389/about Legal business disclaimers: http://www.CraneSoftwrights.com/legal
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] xsl:if test = empty strin, Jorge | Thread | Re: [xsl] xsl:if test = empty strin, Jorge |
Re: [xsl] xsl:if test = empty strin, Liam R E Quin | Date | Re: [xsl] xsl:if test = empty strin, Jorge |
Month |