How to test for missing attribute in XSL? - xslt

What I have is following:
<xsl:variable name="myvar" select=".//spss:category[((not #varName) or #varName=$colVarName) and #text=$series]/spss:cell/#text"/>
What it should do is select the text of the spss:cell's text-Attribute as long as it is a child of a spss:category that has
either a varName Attribute with a value equal to $colVarName
OR no varName Attribute at all
What is happening is following error message (sorry translating here, so just the gist of it):
Expected Token ')'. Found Token '#'.
.//spss:category[((not -->#<-- varName) or #varName=$colVarName...
Problem Solved! (See below)

OK, I think I found the mistake:
not must be used with parenthesis, so instead of
(not #varName) or #varName=$colVarName
it should have been
not(#varName) or #varName=$colVarName

indeed - not() is a function that returns the boolean opposite of whatever is between the parens. If necessary - it will cast its argument to a boolean. In this case, an empty node set casts automatically to false, so if #varName gives you an empty node set, not(#varName) will be true.

Related

Accessing the attribute of a child node through a variable

I am using XLS through C# and I need to be able to access the attributes of a specific node, but whatever I do I get the same "eof with #" error. Am I doing something wrong? Is there something I am missing? This is a code sample:
<xsl:value-of select="$main[1]#index"/>
Error message:
System.Xml.Xsl.XslLoadException: 'Expected end of the expression, found '#'.
$main[1] -->#<-- index'
To select an attribute named index of the context element use #index. Use that in a separate step if you first select elements e.g. foo/#index selects the index attributes of all foo children of the context node.
$main[0] doesn't make much sense as in XPath the first item has the index 1 so perhaps $main[1]/#index is what you want, it depends on how the variable or parameter main has been bound to a value.

Xquery statement to get a value for specific name

I am trying to write a xquery to get the Value for a specific name .Below is the request payload: i.e. if the Name ="ID" then get the
"Value" for that tag (i.e.1000000000.)If the Name="User" get the "Value" for that tag( ie."US").
<not:Items xmlns:v5="http://www.example.com"
xmlns:com="http://commom.com
xmlns:not="http://services.not.com"
xmlns:com1="http://common1.com">
<not:Array>
<com1:Item>
<v5:List>
<com:extensionsItem>
<com:Name>ID</com:Name>
<com:Value>1000000000</com:Value>
</com:extensionsItem>
<com:extensionsItem>
<com:Name>User</com:Name>
<com:Value>US</com:Value>
</com:extensionsItem>
</v5:List>
</com1:Item>
</not:Array>
</not:Items>
I tried the options below:
<ns2:ID>{fn:data($Items/not:Array/com1:Item/v5:List/com:extensionsItem[1]/com:Value)}<ID>
This statement works . But I cannot assure that ID will always come in first element in the array of List.So i want a statement that will work even if ID comes in any other
place in the array and I can retrieve the value.
Thanks in advance
I think you simply want to apply a predicate $Items/not:Array/com1:Item/v5:List/com:extensionsItem[com:Name = 'ID']/com:Value

Is there any point to string(string(.)) in XSLT?

I am dealing with some auto-generated XSLT code.
It contains the following:
string(string(.))
number(string(.))
string(number(string(.)))
Is there any point to these? Or are they reducible to
string(.)
number(.)
string(.)
?
Like Martin says.
There are edge cases in XPath 2.0 where number(string(.)) is not exactly the same as number(.), for example if the context item is an instance of xs:gYear then number(.) will fail but number(string(.)) will succeed; contrariwise, if the context item is a boolean, number(.) will convert true to 1 and false to 0, while number(string(.)) converts both to NaN. But it's very unlikely that these edge cases are important to your application.
For the first one I am pretty sure it can be reduced to string(.). For the third one I don't think you can reduce it to string(.) as for instance for the context node having a character as its string content (e.g. <foo>a</foo>) doing number(string(.)) gives you the special number value "not a number" and if you do string() on that again you get (http://www.w3.org/TR/xpath/#section-Number-Functions, http://www.w3.org/TR/xpath/#section-String-Functions) the string "NaN". I am not sure about the second being reducible, maybe you can check the details of edge cases with the links I provided.

How to make =NULL work in SQLite?

Given the following table:
Table: Comedians
=================
Id First Middle Last
--- ------- -------- -------
1 Bob NULL Sagat
2 Jerry Kal Seinfeld
I want to make the following prepared query:
SELECT * FROM Comedians WHERE Middle=?
work for all cases. It currently does not work for the case where I pass NULL via sqlite3_bind_null. I realize that the query to actually search for NULL values uses IS NULL, but that would mean that I cannot use the prepared query for all cases. I would actually have to change the query depending on the input, which largely defeats the purpose of the prepared query. How do I do this? Thanks!
You can use the IS operator instead of =.
SELECT * FROM Comedians WHERE Middle IS ?
Nothing matches = NULL. The only way to check that is with IS NULL.
You can do a variety of things, but the straight forward one is...
WHERE
middle = ?
OR (middle IS NULL and ? IS NULL)
If there is a value you know NEVER appears, you can change that to...
WHERE
COALESCE(middle, '-') = COALESCE(?, '-')
But you need a value that literally NEVER appears. Also, it obfuscates the use of indexes, but the OR version can often suck as well (I don't know how well SQLite treats it).
All things equal, I recommend the first version.
NULL is not a value, but an attribute of a field. Instead use
SELECT * FROM Comedians WHERE Middle IS NULL
If you want match everything on NULL
SELECT * FROM Comedians WHERE Middle=IfNull(?, Middle)
if want match none on NULL
SELECT * FROM Comedians WHERE Middle=IfNull(?, 'DUMMY'+Middle)
See this answer: https://stackoverflow.com/a/799406/30225

Determining if a string is not null/blank and is a number and not 0?

I normally don't work in ColdFusion but there's a FTP process at work I have to create a report for with the only option right now being a ColdFusion 8 server. This FTP feed has a few issues (trash too).
So, I make the query and then I need to convert some of the string values during the output to do some math. Before that:
How do I tell if a field in the output loop: is not blank or null, is string that can be converted into a valid number, and is not 0?
Is there a simple way of doing this w/o a lot of if statements?
Thanks!
So you want to make sure that the variable is numeric but not zero?
Then you want this:
<cfif IsNumeric(MyVar) AND MyVar NEQ 0 >
Determining if a string is not null/blank and is a number and not 0?
Here's the code I would use in this case.
<cfif isDefined(stringVar) and len((trim(stringVar))) and isNumeric(stringVar)>
do stuff here
</cfif>
isDefined returns a true if the variable exists. If you know the scope of the variable, i.e., its in the form or url scope for instance, you can use structkeyExists(form,"stringVar"). I would recommend using this approach if you know the scope of the variable.
Len(trim(stringVar)) is the second check. First off it trims any leading or trailing empty spaces from the string - this makes sure that any empty variables are not passed along. Then if something is there it will return the length of the string. If its empty len will return a 0.
isNumeric(stringVar) returns a true if the variable is a number and false otherwise.
<cfif Len(field) and Val(field)>
Len() will verify the field has length (not blank--there are no NULLs in CF) and Val() will automatically convert the first character in the string into into a number--or return 0 if it cannot.
Take note of Peter's comment below; although this is the least verbose answer, Val() may fail in certain edge conditions below, ie. The field is a string but starts with a number, incorrectly converting it to a number, and evaluating to TRUE.
<cfif isNumeric(myfield) and myfield gt 0>