How to use null values in a datadriven approach (xsi:nil="true") from an Excel datasource?
We have a request that needs to pass a null value in a particular scenario. Our requests have an Excel datasource that we use for parameters.
The issue we have, is that we are unable to parametize the null value in excel, it simply does not work., we get the error: "cvc-type.3.1.3: The value 'xsi:nil="true"' of element 'AccountNumber' is not valid"
When we use the notation below, it works properly, but in this case we are not using the datasource
When we use the datasource, the notation changes to;
Using the datasource causes the error already mentioned
"cvc-type.3.1.3: The value 'xsi:nil="true"' of element 'AccountNumber' is not valid"
How can we parametize the null value from an excel datasource?
We are using ReadyAPI 2.5.0
Solved! Go to Solution.
Im just trying to get it straight in my head, can you clarify the following?
You are using excel as the datasource....what is the content of the fields in the .xls....is this the source of the the tag values for the xml?
Or is the whole xml payload in there?
If i understand you correctly you are trying to insert a null value, but what do you actually mean by this? Xml doesnt really display blanks as null...depending on the rules typically defined in a schema, instead of displaying the element with null as the value, this would be represented by an empty element....do you mean you want to generate an empty element?
Empty elements are represented as either of the follows:
However, if your schema defines the element as nillable (e.g. <Tagname xsi:nill="true">), this means the tag can be empty but its still displayed in the xml instance.
Can you see why i'm a little confused?
Can you add a bit more detail?
Thanks for your reply, I will try to explain myself better. The field we are using is nillable in the schema, and it works fine when the request has the element represented in this format in the request <Tagname xsi:nill="true"/>
There are no problems when the request is like mentioned above.
The representation above, is not using a datasource, it is hardcoded in the request.
However, when we try to use a datasource for the same request that is when we have the problem. We create a property that points to a cell in excel, in this cell we have our properties/parameters, for one scenario, we have to use a null value. So, in the cell we are entering the value xsi:nil="true" Expecting that this will be process as a null value in the request, but it does not work
When we look at the request that fails, the element in the request is represented as;
<Tagname>xsi:nil="true"</Tagname> which is different to the one that works that is <Tagname xsi:nill="true"/>
The question is, how can we use a datasource to pass a null value or xsi:nil="true" for the scenarios that needed
Or do we need to have a request with the hardcoded property as <Tagname xsi:nill="true"/> for it to work
Hi, you may be able to use groovy to get the generated xml and replace alle instances of <Tagname>xsi:nil="true"</Tagname> to the required <Tagname xsi:nill="true"/>.
Sorry for the delayed response - sorry I've been busy at work and I wanted to setup a VIRT to try and replicate your behaviour before responding.
The trouble is XML doesn't really have a concept of null and that's why there's not much out there if you try googling - there's arguments about whether an empty element with no value is the same as an empty element specifying the null, etc., although theory looks like it leans a certain way.
The other problem appears to be that typically an XML parser reads <TagName /> to be equivalent to <TagName></TagName> even though it appears that your application under test doesn't like this
As @asseldonk01 says - you can use groovy to handle this so.
One option is to use an event handler to replace the problematic string with what you need - I've done this lots of times before - and works great.
The eventhandler is 'RequestFilter.afterRequest' (published in soapui.org) that is pretty handy - for altering responses accordingly.
So essentially you have
which you need to change to
The script below is supposed to replace "</Tagname> with " />
the code is something like the following:
def content = context.httpResponse.responseContent content = content.replaceAll("\""<\/Tagname>", "\" \/>") //log.info( content ) context.httpResponse.responseContent = content
If you create an 'RequestFilter.afterRequest' event handler and add in the above code - this should replace all instances of "</TagName> with " />, so that <Tagname>xsi:nil="true"</Tagname> is changed to <Tagname xsi:nill="true" />
Please note! I struggle with escaping - I think I've got it right - but you'll have to run it to be sure. Also - I don't know whether your parser accepts a space character between the quote marks of the 'true' followed by /> or whether the quote mark is directly adjacent to the />.
The script inserts a space so you might have to remove the space from "\" \/>") so it reads "\"\/>")
Hope this helps - this approach will definitely work if the escaping is correct!
hold it - I'm suggesting groovy script and @rao's suggesting the out the box functionality?
what is the world coming to? 🙂
Hi richi and everyone else;
I have to thank you all for you suggestions I appreciate them. Your ideas guided me towards the solution that I needed. Now it is working. I ended up using the “RequestFilter.filterRequest” as I had to change the request values before submitting it. (not the response, sorry if I did not explained this properly earlier)
Our request data is read from a datasource, sometimes we need to use null values to test different scenarios.
The idea is to replace a null string representation fed through a data source for the actual null that ready api uses. This needs to be done for every node that needs it before submitting the request
So, if we have a request has two or five or more nodes that need to send a null value equivalent then, this solution applies no matter the node name, it should work also at any level in the hierarchy, but I have not tested this yet
The objective if to search for the string representing null, in my case it is “>xsi:nil="true"</TagName> using regular expression to target any tagname
The solution consist in creating a RequestFilter.filterRequest and add the following code:
def reqContent = context.requestContent
content = reqContent.replaceAll(">xsi:nil=\"true\"</[A-Za-z]+>", " xsi:nil=\"true\" />")
context.requestContent = content
You sorted it out! Nice one.....can you give yourself kudos? Cos if you can you should!
Cheers for providing the clear explanation on the resolution too....it'll definitely help if someone else comes across the same problem and finds your post.