I have xml with flag:<ns4:flag>false</ns4:flag>. And I want to read this flag and set it's value to FLAG property:
.setProperty( FLAG, xpath("//*[local-name()='flag']/text()", Boolean.class))
Using code above I get 'true' value instead of 'false'. Also tried resultType(Boolean.class) and boolean() xpath function inside expression, but it didn't work out. Any ideas how can I do this cast?
In XPath, the following expression will return boolean value true when the text content equals string value "true", and return boolean value false otherwise :
//*[local-name()='flag']/text() = 'true'
xpathteseter.com demo
So I guess, changing your XPath expression to the above XPath would work.
Related
I'm trying to replace an empty field with nulls in an UpdateRecord processor.
/title ${field.value:replaceEmpty(null)}
This fails because "null" is not a valid keyword. How does one specify null in the nifi expression language?
You can use the literal() function to return a String value that is the exact input to the function, and you can nest that inside your replaceEmpty method. Try using the expression ${field.value:replaceEmpty(${literal('null')})}.
If you are doing this in the UpdateRecord processor, you want to use Apache NiFi RecordPath syntax, not Expression Language. I believe the CSVReader and others parse even a field value containing only spaces to empty, so a regular expression like replaceRegex( /title, '^(?![\s\S])$', 'null' ) doesn't work.
My suggestion would be to file a Jira requesting this capability. In the mean time, do not use UpdateRecord for this, but rather ReplaceText with a regular expression like ,\s?, for an empty CSV value and replace it with null.
There is a trick using RecordPath, if the field value is blank you can do this to get a null value.
/fieldName[not(isBlank(/fieldName))]
It is giving answer as
{
"fieldname" : "null"
}
here null is a string not a null value.
I'm using SoapUI to test a WCF service. I have an XPath Match assertion in which the Declare is:
if (boolean(//a:IsClick/text()[1])) then //a:IsClick else ''
For the source XML, the node is
<a:IsClick>false</a:IsClick>
so the Declare section equates to 'false'.
The Expected box has this:
${#ResponseAsXml#(//CLICK[text()],'')}
and the XML (from a JDBC Test Step) is:
<CLICK>0</CLICK>
so the expected value is 0.
I need to have these two equate so my assertion will pass. One way to do this would be to cast the Expected result from 0 to 'false'. How can I do that? Or is there a better approach?
In XPath the boolean() function returns a boolean for number, string, or node-set. In your case where you want to cast a number to a boolean, boolean(0) returns false, for the rest of numbers boolean(n) returns true. In the other hand boolean() of string returns false for boolean('false') or for boolean('') (empty string) for the rest of strings boolean() returns true. So your problem is that using text() you're getting the '0' as string instead of a number so when you try to cast boolean('0') you're getting true.
In your case if you've some XML result from your JDBC Test Step like:
<Results>
<CLICK>0</CLICK>
</Results>
You can convert this 0 to false adding boolean() to your expression and also using number() function instead of text(). So to cast the 0 to false use:
${#ResponseAsXml#(boolean(//CLICK[number()]))}
instead of:
${#ResponseAsXml#(//CLICK[text()],'')}
Hope this helps,
The simplest solution is to turn this into a Groovy problem - a Groovy assertion.
Here is a visualization (see documentation):
def negIsClick = "false"
def negCLICK = "0"
def posIsClick = "true"
def posCLICK = "1"
// fake "cast" the text to boolean
assert !(negIsClick.equals("true") ?: false)
assert (posIsClick.equals("true") ?: false)
assert !negCLICK.toInteger() // zero is false
assert posCLICK.toInteger() // all other numbers are true
// note the exclamations everywhere
assert !(negIsClick.equals("true") ?: false) == !negCLICK.toInteger()
assert !(posIsClick.equals("true") ?: false) == !posCLICK.toInteger()
// this fails
assert (negIsClick.equals("true") ?: false) == negCLICK.toInteger()
The last one fails, because you cannot compare a boolean to an integer. But in the cases before that, the ! first casts everything to booleans.
So in your case, you will need to do something like:
// read in the two values
def IsClick = context.expand( '${XML test step#Response//*:IsClick}' )
def CLICK = context.expand( '${JDBC test step#ResponseAsXml//*:CLICK}' )
// now compare them
assert !(IsClick.equals("true") ?: false) == !CLICK.toInteger()
assert '1'.toInteger().asBoolean()
assert !'0'.toInteger().asBoolean()
I have an xml like this:-
<include><method wrap="true"><name>methodA</name></method>...</include>
method node can have wrap attribute with value true or false. absence of attribute should mean it is false.
my predicate is like this:-
//include/method[matches(str, methodA)]
to get the matching nodes.
How can I get the wrap attribute and figure if the attribute is missing?
Try this:
//include/method[#wrap='true'][name = 'methodA']
The test for wrap attribute will only be true if there is an attribute wrap and the value is string true.
<DocumentList>
<DocumentId>node1175251</DocumentId>
<DocumentId>node1175254</DocumentId>
<DocumentId>node1175385</DocumentId>
</DocumentList>
I have this Xml.
I want to select the value of DocumentId.
I need xpath for select the value. Anyone Help me?
I want to select the value of DocumentId. I need xpath for select the
value. Anyone Help me?
This selects all DocumentId elements:
/*/DocumentId
This selects the first DocumentId element:
/*/DocumentId[1]
This selects the second DocumentId element:
/*/DocumentId[2]
This selects the last DocumentId element:
/*/DocumentId[last()]
All of the above XPath expression select nodes (elements).
An XPath expression doesn't select a value. It may produce a value. Also, what you are actually asking for is the string value of a particular DocumentId element:
This Xpath expression produces the string value of the first DocumentId element:
string(/*/DocumentId[1])
This Xpath expression produces the string value of the second DocumentId element:
string(/*/DocumentId[2])
This Xpath expression produces the string value of the last DocumentId element:
string(/*/DocumentId[last()])
/DocumentList/DocumentId
/DocumentList/DocumentId[1] // for the first instance
/DocumentList/DocumentId[last()] // for the last instance
Also, /DocumentList/ would ensure that /DocumentId[1] is inside DocumentList tag
use .eq( index ) java script function
to get the value of xml node using index as parameter
I have a page that searches with filters. I have this code for example,
xmlTempResultSearch = xmlResidentListDisplay.selectNodes("//PeopleList/Row[#LastName != '"+txtSearch.value+"']");
xmlTempResultSearch.removeAll();
This selects the data that is not equal to the LastName inputted on the txtSearch textbox and then removes them from the result set so that its filtered to equal the last name on the txtSearch textbox.
My problem with this code is that it should be equal (=) to the txtSearch.value, what I want is that I want the result set LIKE the txtSearch.value. What happens on my page is that when I type 'santos' on the txtSearch textbox, its result set is all those last names with 'santos'. But when I type 'sant', nothing appears. I want the same result set with 'santos' because it all contains 'sant'
You can use all of the XPath (1.0) string functions. If you have XPath 2.0 available, then you can even use RegEx.
contains()
starts-with()
substring()
substring-before()
substring-after()
concat()
translate()
string-length()
There is no **ends-with() in XPath 1.0, but it can easily be expressed with this XPath 1.0 expression**:
substring($s, string-length($s) - string-length($t) +1) = $t
is true() exactly when the string $s ends with the string $t.
You can use start-with function and not function. Reference:
http://www.w3schools.com/xpath/xpath_functions.asp
xmlTempResultSearch = xmlResidentListDisplay.selectNodes("//PeopleList/Row[not(starts-with(#LastName,'"+ txtSearch.value +"'))]");
you can use contains() function of XPath:
xmlTempResultSearch = xmlResidentListDisplay.selectNodes("//PeopleList/Row[not(contains(#LastName,'"+txtSearch.value+"'))]");