Error while using fn:string-length in Xquery - xpath

I am trying to use fn:string-length function in Xquery and strangely I am getting this error.
line 19, column 66: {err}XP0004 [{bea-err}XP0004a]: Operator "gt" is not applicable for arguments of type {http://www.w3.org/2001/XMLSchema}integer and {http://www.w3.org/2001/XMLSchema}string
All I am trying to do is, to get a length of a XPath expression and compare it with some value.
{
let $PlaceofDeliveryZoneCodeVal := $getRevenueRequest1/ns0:AlternativeCode/ns0:AlternativeCodeVal/text()
return
if(fn:string-length($PlaceofDeliveryZoneCodeVal) > "8") then
<ns1:GeoId>
<ns1:AlternativeCodeVal>{$PlaceofDeliveryZoneCodeVal}</ns1:AlternativeCodeVal>
</ns1:GeoId>
else()
}

The problem is that because the integer is wrapped in quotes, you are comparing an integer to a string:
(fn:string-length($PlaceofDeliveryZoneCodeVal) > "8")
If you remove the quotes, the comparison will succeed:
(fn:string-length($PlaceofDeliveryZoneCodeVal) > 8)

Related

ODI: KM Java BeanShell - escape double quotes

I want to set a variable inside Knowledge Module's Task, with target technology set to Java BeanShell. The value represents mapping EXPRESSIONs, where source table is inside MSSQL database. Column names are surrounded by double quotes, that causes a problem with templating.
Column expression is:
source_tab."Entry Number"
Task (Java BeanShell)
<$
String SEL_COLS = "<%=odiRef.getColList(0, "", "[EXPRESSION]\t[ALIAS_SEP] [CX_COL_NAME]", ",\n\t", "", "")%>";
$>
This variable assignment fails, because " in source_tab."Entry Number" is not escaped - code does not compile.
odiRef.getQuotedString does not solve the problem...
odiRef.getQuotedString could help if generated code is executed as a final code in JBS technology. When we use it in the following way (in ?-, $- or #-substitution):
<$
String SEL_COLS = <%=odiRef.getQuotedString(odiRef.getColList(0, "", "[EXPRESSION]\t[ALIAS_SEP] [CX_COL_NAME]", ",\n\t", "", ""))%>;
$>
then result fails like this:
... Caused by: org.apache.bsf.BSFException: BeanShell script error:
Parse error at line 3, column 37. Encountered: Entry BSF info: ....
... 11 more
Text: <$
String SEL_COLS = "SOURCE_TAB.\"Entry Number\" ENTRY_NUMBER";
$>.
This looks good but does not work. It could work as final code (I mean result of all substitutions) in JBS Technology. Unfortunately any substitutions eats backslashes.
Ok, if standard odiRef-functtion does not work, lets write our own:
<%
String getQuotedStringCustomized(String s){
return '"'+s.replaceAll('"'.toString(),'"'+"+'"+'"'+"'+"+'"')+'"';
}
%>
-- other code........
<$
String SEL_COLS = <%=getQuotedStringCustomized(odiRef.getColList(0, "", "[EXPRESSION]\t[ALIAS_SEP] [CX_COL_NAME]", ",\n\t", "", ""))%>;
$>
Only the way to put " into a Java literal within the JBS Substitution is contatenation with Char literal '"' or using '"'.toString() expression if it is impossible to use Char type.
FINALLY:
In final JBS code you may use \", but within substitutions only +'"'+.

thymeleaf eq with spring variables bug?

I'm trying to run the following th:if:
th:if="${camelContext.getRouteStatus( route.id )} &eq; 'Hey'
but I get this error:
org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "${camelContext.getRouteStatus( route.id )} &neq; 'Hey' " (camel:92)
However, if I try
th:if="${camelContext.getRouteStatus( route.id )} > 41 "
I get a different error, but now indicating that it's able to parse the expression, its just that it cannot compare Strings and numbers:
Cannot execute GREATER THAN from Expression "${camelContext.getRouteStatus( route.id )} > 41". Left is "Started", right is "41" (camel:92)
That's fine, I just wanted to check if I was writing the syntax correctly, and I don't want to compare numbers anyways, I want to compare the RouteStatus string.
Anyways, maybe someone can help me with this problem? Basically I want to do a if-else on the contents of a string, but I can't get this to work..
Cheers
Have you tried this:
th:if="${camelContext.getRouteStatus( route.id )} == 'Hey'"
Maybe it will work like this?
The example on the thymeleaf shows something similar:
Values in expressions can be compared with the >, <, >= and <= symbols, as usual, and also the == and != operators can be used to check equality (or the lack of it). Note that XML establishes that the < and > symbols should not be used in attribute values, and so they should be substituted by < and >.
th:if="${prodStat.count} gt; 1"
th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"
Even though textual aliases exist for some of these operators: gt (>), lt (<), ge (>=), le (<=), not (!). Also eq (==), neq/ne (!=), it is sometimes still better to stick with the old fashion operators.
It seems that your expression is malformed, but maybe this a copy paste issue.
Could you try: th:if="${camelContext.getRouteStatus( route.id ) eq 'Hey'} ?

How to convert string to double in VBScript?

I need to write some code in VBScript and have a version number string in a text file that I need to compare against. If I write this code as a test:
option explicit
Dim VersionString
VersionString = "6.2.1"
Dim Version
Version = CDbl (VersionString)
Version = Version * 100
I get an error on the CDbl line:
Microsoft VBScript runtime error: Type mismatch: 'CDbl'
How should I read and compare this string value?
"6.2.1" is not a Double formatted as a String. So CDbl() can't convert it. Your options are:
treat versions as strings; ok if you only need to compare for equality, bad if you need "6.9.1" to be smaller that "6.10.2"
Split() the string on "." and deal with the parts (perhaps converted to Integer/Long) separately; you'll need to write a comparison function for such arrays
Remove the "."s and CLng the resulting string; will break for versions like "6.10.2"
Split() the string on "*" and multiply + add the 'digits' to get one (integer) version number (6 * 100 + 2 * 10 + 1 * 1 = 621 for your sample); may be more complex for versions like "15.00.30729.01"
The conversion to a double isn't working because there are two decimal points in your string. To convert the string, you will have to remove one or both of them.
For this, you can use the Replace function. The syntax for Replace is
Replace(string, find, replacewith [, start [, count [, compare]]])
where string is the string to search, find is the substring to find, replacewith is the substring to replace find with, start is an optional parameter specifying the index to start searching at, count is an optional parameter specifying how many replaces to make, and compare is an optional parameter that is either 0 (vbBinaryCompare) to perform a binary comparison, or 1 (vbTextCompare) to perform a textual comparison
' Remove all decimals
Version = CDbl(Replace(VersionString, ".", "")
' Remove only the first decimal
Version = CDbl(Replace(VersionString, ".", "", 1, 1)
' Remove only the second decimal
Version = CDbl(Replace(VersionString, ".", "", 3, 1)

NULL literal in XPath

Is there a NULL literal in XPath 1.0 or 2.0?
My use case is that I have a conditional (if then else) XPath expression and I want to return NULL to signify a certain condition. I am afraid that returning an empty string might be ambiguous in my case as it could be a valid result of the other part of the if then else expression.
The empty sequence () can be used as such. It is also returned if there is no result for a path expression.
let $foo := "foo"
return
if ($foo = ("foo", "bar", "batz")) then
$foo
else
()
You can check for an empty sequence using
let $result := ()
return empty($result)
If you pass the result of the first XPath expression to your native code, you should be able to distinguish "NULL" from the empty string by having no results (empty sequence / "NULL") or having a result string (which could be empty).

If statement not working - what is wrong with this syntax?

I get an "Expected Identifier" message against the if line. Any ideas why?
if ([inputA.text isEqualToString:#""]) && ([inputB.text <> isEqualToString:#""]) {
c = 1;
}
I'm trying to say it both inputs are empty...
I presume there isn't an easier way to say if the text is null in Obj C++?
An if statement requires that its condition expression be enclosed in parentheses. You have a compound expression. You've used parentheses around the subexpressions of the logical AND operation (&&), but you haven't surrounded the entire expression in parentheses. (The subexpressions don't actually require parentheses in this case, but they don't hurt.)
Next, you have a random <> in the second subexpression. What is that doing in there? In some languages that is the "not equal" operator, but a) it's not an operator in C or Objective-C, b) it wouldn't go inside a message-send expression like that, and c) you claim you were trying to check that both inputs are empty, so I wouldn't expect you to try to negate the test for equality with the empty string.
So, fixing just those problems yields:
if ([inputA.text isEqualToString:#""] && [inputB.text isEqualToString:#""]) {
c = 1;
}
That said, pie's answer is good, too. It also works if either of the inputs has a nil text property, too.
if ([inputA.text length]==0 && [inputB.text length]==0)
{
c = 1;
}

Resources