I am having issues using the or operator in XSLT. I need to test if a variable does not equal 00 or 09.
The current value being entered into the XSLT for Timecodehour is 09. I am using the test below to confirm that the value must be 00 or 09.
<xsl:template match="/">
<xsl:if test="$TimecodeHour!='00' or $TimecodeHour!='09'">
<xsl:message terminate="yes">Timecode is not supported</xsl:message>
</xsl:if>
</xsl:template>
The test completes correctly if I removed "$TimecodeHour!='00' or" but submitted message Timecode is not supported when I add it back in again. Could someone please help me understand what I am doing wrong?
You need to use and not or here. or will be true if either of the conditions are true.
So, for example, if $TimecodeHour equals 09 then the expression $TimecodeHour!='00' returns true, and so the result of the or expression is true.
Using and will only return true if both conditions are true.
<xsl:if test="$TimecodeHour!='00' and $TimecodeHour!='09'">
Related
I have problem with my code in XSLT with if. I am using key function and there I find out if something is in the key or not.
<xsl:key name="hlp" match="help" use="#id" />
...
<xsl:if test="key('hlp', #some_id) !=''">
...
</xsl:if>
That is correct it gives me what I want but how I can make opposite condition that #some_id isn´t in key hlp... I mean:
<xsl:if test="key('hlp', #some_id) <!--is equal--> ''">
...
</xsl:if>
Is there something like that in XSLT/XPath?
When you call key('x', 'y'), the result is the set of nodes in which the key is equal to 'y'. You can test whether a node-set is empty using the empty() function (in XSLT 2.0) or the not() function in XSLT 1.0:
<xsl:if test="not(key('x', 'y'))" version="1.0">...</xsl:if>
<xsl:if test="empty(key('x', 'y'))" version="2.0">...</xsl:if>
or for the inverse test (to test if something was found):
<xsl:if test="key('x', 'y')" version="1.0">...</xsl:if>
<xsl:if test="exists(key('x', 'y'))" version="2.0">...</xsl:if>
Testing by comparing the result against a string is wrong. The tests key('x','y')='' and key('x','y')!='' will both return false if the result of the key() function is an empty node-set; conversely, if the key() function selects two nodes, one with content and the other without, then both tests will return true.
<xsl:key name="hlp" match="help" use="#id" />
...
<xsl:if test="key('hlp', #some_id) !=''">
...
</xsl:if>
As already pointed by Michael Kay, avoid using the != operator unless truly knowing what it does.
This aside (and the fact that the key() function returns a node-set), it is more in the spirit of XSLT to write the above as:
<xsl:apply-templates select="key('hlp', #some_id)"/>
but how I can make opposite condition that #some_id isn´t in key
hlp... I mean:
<xsl:if test="key('hlp', #some_id) <!--is equal--> ''">
...
</xsl:if> ```
Is there something like that in XSLT/XPath?
Again, in the spirit of XSLT I recommend using code like this:
<xsl:apply-templates select="/*[not(key('hlp', #some_id))]" mode="not-found"/>
In the select expression above one can substitute /* with any existing node in the document -- if this really matters.
I'm trying to find situations where a heading tag (head1) is not followed by a body tag.
Here's a snippet of what I'd be searching for, "head1" followed by "body":
<title role="head1">Third-Party Notices and/or Licenses</title>
<para role="body">Required notices for open source software products or components used by Cloud are identified in the following table along with the applicable licensing information.</para>
And here's the code I'm trying (the empty head1 code works fine):
<xsl:template match="w:p[w:pPr/w:pStyle/#w:val='ahead1']">
<xsl:variable name="elementValue">
<xsl:apply-templates mode="title.text.only" />
</xsl:variable>
<xsl:choose>
<xsl:when test="$elementValue = ''">
<xsl:message>ERROR: Encountered an head 1 paragraph with no text content.</xsl:message>
<xsl:call-template name="revealDocPosition"/>
</xsl:when>
<!-- Code to check to see that a head1 is directly followed by a body tag -->
<xsl:when test="[$elementValue]and not[following-sibling::*[1][self::atgbody]]">
<!-- <xsl:when test="not[$elementValue][following-sibling::*[1][self::atgbody]]"> -->
<xsl:message>ERROR: Encountered an atg head 1 paragraph that was not follwed by an atgbody.</xsl:message>
<xsl:call-template name="revealDocPosition"/>
</xsl:when>
It fails in my build because it doesn't like the syntax:
[java] Error at xsl:when on line 30 column 84 of headings.xsl:
[java] XPST0003: XPath syntax error at char 0 on line 30 in {[$}:
[java] Unexpected token "[" in path expression
[java] Failed to compile stylesheet. 1 error detected.
I've tried different syntax and it either fails, or run and doesn't find the error.
Ideas?
The square braces are a predicate, and are used to filter items that do not evaluate to true when the predicate filter is applied.
The expression [$elementValue] has nothing to test and filter on.
Assuming that you are attempting to test whether $elementValue is "truthy" and has content, you need to move it outside of the predicate and just test the variable.
The expression not[following-sibling::*[1][self::atgbody]] is testing whether there is a child element named not and applying a predicate filter, which will never match since you don't have any not elements - so this test will never be true. You need to change [] to () in order to invoke the not() function.
<xsl:when test="$elementValue and not(following-sibling::*[1][self::atgbody])">
test="[$elementValue]and not[following-sibling::*[1][self::atgbody]]"
You seem to be making this up as you go along. Guessing the syntax isn't going to get you anywhere.
I don't know what's in the variable $elementValue because you haven't shown enough of your code. Your code refers to an atgBody element which doesn't appear in your source document snippet, and the match pattern also refers to nodes that aren't in your source snippet. This means it's difficult to see what your code is trying to achieve and therefore to tell you exactly where it's wrong.
The syntax error is that [$elementValue] isn't a legal expression. Without knowing what you thought it might mean, it's impossible to tell you how to correct it.
The following is giving me the "memberstable is an unexpected token" error.
<xsl:when value-of memberstable/#member_cancontactthem =1>
<td bgcolor="#ff00ff">
<xsl:value-of select="You can contact this member"/></td>
</xsl:when>
I've used this to initialize it:
<xsl: value of select = "memberstable/#member_cancontactthem" />
The value in the DB is boolean, so either 1 or 0.
Until now, all suggestions will produce errors if I am not mistaken. xsl:when needs a test attribute:
<xsl:when test="memberstable[#member_cancontactthem='1']">
is the correct syntax. Also, xsl:when must be inside an xsl:choose element.
In general, please be careful with whitespace, and with hyphenations (for instance, value of is not the same as value-of) and make sure all attribute values are between quotes. XSLT must respect the rules of XML, which is not as forgiving as HTML.
<xsl:variable name="date1" select="2011-10-05"/>
<xsl:variable name="date2" select="2011-10-05"/>
<xsl:variable name="date3" select="2011-10-06"/>
<xsl:if test="$date2 = $date1 or $date2 < $date1">
..do something
</xsl:if>
<xsl:if test="$date3 = $date1 or $date3 > $date1">
.. do something
</xsl:if>
Both should evaluate true, but the second if doesn't. For the life of me I can't comprehended why!
In the actual transform the dates themselves are being drawn from an XML document but debugging through VS2010 i can see the values are as above.
Must be something fairly fundamental i'm doing wrong - any help would be brilliant!
I tried this in Oxygen/XML... select="2011-10-05 is being interpreted as an arithmetic expression, giving the value 1996 (2011 minus 10 minus 5) and "2011-10-06" is intrepreted as 1995.
What you want is
<xsl:variable name="date1" select="'2011-10-05'"/>
<xsl:variable name="date2" select="'2011-10-05'"/>
<xsl:variable name="date3" select="'2011-10-06'"/>
Note the extra single quotes.
From the XSLT 1.0 Specification:
If the variable-binding element has a select attribute, then the value
of the attribute must be an expression and the value of the variable
is the object that results from evaluating the expression.
I am creating XSLT file.
I have one variable which take value from XML file.But it may happen that there is no reference in xml for the value and at that time XSL variable will return False/None(don't know).I want keep condition like,If there is no value for the variable use the default one.
How to do that ?
With the few details given in the question, the simplest test you can do is:
<xsl:if test="$var">
...
</xsl:if>
Or you might use xsl:choose if you want to provide output for the else-case:
<xsl:choose>
<xsl:when test="not($var)"> <!-- parameter has not been supplied -->
</xsl:when>
<xsl:otherwise> <!--parameter has been supplied --> </xsl:otherwise>
</xsl:choose>
The second example will also handle the case correctly that the variable or parameter has not been supplied with an actual value, i.e. it equals the empty string. This works because not('') returns true.
You haven't explained what you mean by "has no value". Here is a generic solution:
not($v) and not(string($v))
This expression evaluates to true() iff $v "has no value".
Both conditions need to be met, because a string $v defined as '0' has a value, but not($v) is true().
In XSLT 1.0 using a default can be achieved in different ways if the "value" is a node-set or if the value is a scalar (such as a string, a number or a boolean).
#Alejandro provided one way to get a default value if a variable that is supposed to contain a node-set is empty.
If the variable is supposed to contain a scalar, then the following expression returns its value (if it has a value) or (otherwise) the desired default:
concat($v, substring($default, 1 div (not($v) and not(string($v)))))
You can use string-length to check, if a variable called $reference for example contains anything.
<xsl:choose>
<xsl:when test="string-length($reference) > 0">
<xsl:value-of select="$reference" />
</xsl:when>
<xsl:otherwise>
<xsl:text>some default value</xsl:text>
</xsl:otherwise>
</xsl:choose>
If necessary use normalize-space, too.
First, all variables has values, because XSLT belongs to declarative paradigm: there is no asignation instruction, but when you declare the variable you are also declaring the expression for its value relationship.
If this value it's a node set data type (that looks from your question), then you should test for an empty node set in case nothing was selected. The efective boolean value for an empty node set is false. So, as #0xA3 has answered: test="$node-set".
You wrote:
If there is no value for the variable
use the default one. How to do that ?
Well, that depends on what kind of data type you are looking for.
Suppose the node set data type: if you want $node-set-1 value or $node-set-2 if $node-set-1 is empty, then use:
$node-set-1|$node-set-2[not($node-set-1)]
I tried a lot of solution from SO, my last solution was taken from #dimitre-novatchev, but that one also not working every time. Recently I found one more solution from random google search, thought to share with the community.
In order to check empty variable value, we can declare an empty variable and compare its value against test condition. Here is code snippet:
<xsl:variable name="empty_string"/>
<xsl:if test="testVariableValue != $empty_string">
...
</xsl:if>
Here testVariableValue hold the value of new variable to be tested for empty
scenario.
Hope it would help to test empty variable state.