Willi Fischer
Willi Fischer

Reputation: 455

Difference between != and not ( = )

What is the difference between the not() operator and !=?

See this example:

<?xml version="1.0" encoding="UTF-8"?>
<body>
    <test>123</test>
</body>

<xsl:template match="/">
<xsl:if test = "/body/test = (123, 2)">true1</xsl:if>
<xsl:if test = "not(/body/test != (123, 2))">true2</xsl:if>
</xsl:template>

http://xsltransform.net/jyH9rMx

Why do i get true1 as a result, but not true2? I would expect the two lines to be equivalent. Why are they not?

Upvotes: 5

Views: 7416

Answers (4)

Michael Kay
Michael Kay

Reputation: 163262

It might be worth noting the difference between how XPath handles this and how SQL handles it. SQL uses three-valued logic and NULL values, so the effect is that if AUTHOR is absent (null) then AUTHOR="Kay" and AUTHOR!="Kay" both produce "null" (or "undefined", I think they call it), which means that when either expression is used as a predicate in a WHERE clause, the relevant row is not selected. XPath also produces the result that if AUTHOR is absent, neither of the predicates AUTHOR="Kay" and AUTHOR!="Kay" cause the item to be selected; but unlike SQL, there is no three-valued logic, and this is achieved by having both predicates return false. But the consequence of the predicate returning false is that its inverse (not(P)) returns true, which leads to the surprising result that not(AUTHOR="Kay") has a different effect from AUTHOR!="Kay".

Upvotes: 2

Ian Roberts
Ian Roberts

Reputation: 122364

The key thing to realise with the "general" comparison operators in XPath (including = and !=) is that they are implicitly existentially quantified over their argument sequences. The expression X = Y means the same as the explicitly quantified expression

some $x in X, $y in Y satisfies $x eq $y

(eq being the single item equality operator). So not(X = Y) means

not(some $x in X, $y in Y satisfies $x eq $y)

which is equivalent to saying

every $x in X, $y in Y satisfies $x ne $y

Conversely X != Y means

some $x in X, $y in Y satisfies $x ne $y

Upvotes: 3

Mathias M&#252;ller
Mathias M&#252;ller

Reputation: 22617

I have no idea why you are testing against a sequence of items, but the reason

/body/test != (123,2)

returns true is that there is indeed one element in this sequence which is not equal to the value inside test, namely "123". This kind of condition returns true, even if not all items in a sequence pass the test.

If you remove ,2 from this sequence:

/body/test != (123)

this will no longer return true, and its inverse

not(/body/test != (123)

will return true.

Stylesheet

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="text" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="/">
        <xsl:if test = "/body/test = (123,2,3,4)">true1</xsl:if>
        <xsl:if test = "not(/body/test != (123))">true2</xsl:if>
    </xsl:template>

</xsl:transform>

Result

true1true2

Upvotes: 1

michael.hor257k
michael.hor257k

Reputation: 116959

To answer the question/s you didn't ask, but should have:

"123 = (123, 2)"

returns true because 123 is equal to 123.

"not(123 = (123, 2))"

returns false because as shown above, the inner expression is true - and the outer not() merely reverses it.

"123 != (123, 2)"

returns true, because 123 is not-equal to 2.

"not(123 != (123, 2))"

returns false because as shown above, the inner expression is true, and the outer not() merely reverses it.

For reference, see: http://www.w3.org/TR/xpath20/#id-value-comparisons

Upvotes: 6

Related Questions