Good afternoon,
The problem:
I'm trying to count output nodes in a biztalk mapping.
I don't want to use the record count functoid or a xslt transformation since there are a lot of conditions that determine if the node is generated.
What I tried:
I created a script functoid and declared a global variable (in C#).
// global to save count
public int E1_Record_Count = 0;
I created a script functoid to output the global variable and tied it to my output node:
public string E1_Records()
{
return E1_Record_Count.ToString();
}
I created a script functoid and that is connected to the logical functoid that controls if a node is produced. This script counts the number of nodes created:
public void IncrementE1Count( string isOutput )
{
try
{
if ( System.Convert.ToBoolean( isOutput ) )
++E1_Record_Count;
}
catch
{
}
}
What doesn't work:
I always get zero as result. I've changed the global declaration and the output changes so the global seems to be declared, initialized and output correctly. Creating a second declaration for the global throws an error so there's only one global instance of the variable.
I commented out everything but the increment line in the script to change the global. This makes me think it's never being executed. This script functoid is tied to the same logical functoid that controls the output nodes (which I do get).
Any ideas what's going wrong?
I'm using Biztalk Server 2010.
Since the script functoid had no output the new xslt 2 evaluator used in biztalk 2010 optimized away any calls to it.
If I add a output value and connect the script functoid containing the increment function to an output node then it gets called and it works.
Any output from this function has no value since the count of nodes will be incomplete when it's called. So I need to output something, but I have nothing of any value. I changed the function to return a constant string which I used to set a node that required a constant value.
It's not a nice hack but I don't see any other easy way to trick xslt into evaluating it.
I believe I've solved something similar to this years ago by setting a value BEFORE the mapping and/or doing the counting outside of the mapping. Depending on XSLT (the mapper) for keeping state (counts, etc.) is something I just try to avoid. Probably not the answer your looking for, but I use .NET helper classes way more than trying to out trick XSLT and the mapper.
I found it was simplest to create an orchestration and use two sequential transformations to count the nodes.
Related
Im working on rosparam and I have exercise here to have a node that prints out a number. I can change the number through params. Theres another condition in which the node can run multiple times unless it has different number from previous nodes. Any idea on how to check the parameter of the previous nodes?
ROS params are stored globally on the ros param server. This means that individual nodes don't really own the param value themselves. Instead you should just be pulling params normally with the correct namespace. You can see the difference in namespacing below
std::string global_name, relative_name, other_node_name;
ros::param::get("/global_name", global_name);
ros::param::get("relative_name", relative_name);
ros::param::get("/some_node/param_number", other_node_name);
I want to accomplish the following into Robot Framework
I want to store a Text from an Element xpath://*[#id="plsAttachGrid_0_1"]into a Scalar ${name3}, however, the Element is not always available on the web page, therefore, I need to run a IF/ELSE statement in order to avoid an Error when the Element is not available
My idea was the following:
${countt2}= Get Element Count xpath://*[#id="plsAttachGrid_0_1"]
Run Keyword If ${countt2}>0
${name3}= Get Text xpath://*[#id="plsAttachGrid_0_1"]
ELSE LOG NO_FILE
However, I have learnt It is not possible to store into a Scalar inside Run Keyword If, since it is expecting a Keyword.
Therefore, how can I accomplish it?
A keyword inside Run Keyword If can return a value that propagates up - e.g. can be assigned to a variable placed before the Run Keyword If; so in your case:
${name3}= Run Keyword If ${countt2}>0 Get Text xpath://*[#id="plsAttachGrid_0_1"]
So now ${name3} will have the return value of Get Text when ${countt2}>0.
What will its value be if the condition is not met? It'll be None (the data type, not a string), as the variable is now declared, but not explicitly defined.
You can set it to a different value in this case, to handle it easier later in the code:
${name3}= Run Keyword If ${countt2}>0 Get Text xpath://*[#id="plsAttachGrid_0_1"]
... ELSE Set Variable not_set # or ${0}, or any other value you need for ${countt2}<=0
I have an API request that I need to run in Postman-Collection-Runner thru multiple iterations. The API request uses Variable.
How can I make this variable to automatically increase with each iteration (or maybe set the iteration value as another Variable)?
If I understand your question correctly, you would like to assign different values to a variable in the request in different iterations which is achievable in 2 ways.
a) Using data files
https://learning.getpostman.com/docs/postman/collection_runs/working_with_data_files/
The data files could be in JSON or CSV format. Unfortunately, there is no way in Postman to tie the variable values to another variable unless you want to do it in a hacky way!
b) Pre-request & Tests scripts
1- Initialise the environment variable in the Pre-request Scripts like this:
var value = pm.environment.get("var");
if( !value) {
pm.environment.set("var", 1);
}
2- Increment the variable value in Tests
var value = pm.environment.get("var");
pm.environment.set("var", value+1);
This creates an environment variable and increments it after each iteration. depending on how you structure your collection you might need to consider flushing/resetting the environment variable to be ready for the next run
It worth mentioning that Pre-request Scripts and Tests running before and after the requests respectively, so you can write any scripts that would like to run after the request in the Tests. It shouldn't be necessarily a test!
1. Using Global pm.* functions and Variables in Pre-Request Scripts/Tests
Pre-Request script - runs before executing the request
Tests - runs after executing the request
a.
pm.variables.set("id", pm.info.iteration);
Ex: example.com/{{id}}/update gives
example.com/0/update
example.com/1/update etc...
Number of iterations is set in Collection Runner. pm.info.iteration key has the current iteration number, starting at 0.
b.
var id = +pm.globals.get("id");
pm.globals.set("id", ++id);
The variables can be in any scope - globals/collection/environment/local/data.
In Collection Runner, check the Keep Variable Values checkbox, to persist the final value of the variable in the session (here id).
Note: If the variable is accessed via individual scopes (via pm.globals.* or pm.environment.* or pm.collectionVariables.*), then the mentioned checkbox should be toggled as required. Else if accessed via local scope (pm.variables.*), the value will not be persisted irrespective of the checkbox.
Ex: Same as above
More on variables and scoping
2. Using Dynamic variables
These variables can be used in case random values are needed or no specific order is necessary.
a. $randomInt - gives a random Integer within 1 - 1000.
Ex: example.com/{{$randomInt}}/update gives
example.com/789/update,
example.com/265/update etc...
b. $timestamp - gives current UNIX timestamp in seconds.
Ex: example.com/{{$timestamp}}/update gives
example.com/1587489427/update
example.com/1587489434/update etc...
More on Dynamic variables
Using Postman 7.22.1, while answering this. New methods may come in future.
What I'm really doing is trying to set a watchpoint on the setting or clearing of a single bit. I do that by setting a watchpoint on the word containing the bit, then making it conditional on *word & mask (for setting, or (~*word) & mask for clearing.)
The problem is that some other bit in the same word may be modified, and the condition may happen to already match. If I had the old and new values, I could set a condition of (($old ^ $new) & mask).
I looked at the python gdb.Breakpoint class, but it doesn't seem to receive this information either.
I suppose I could go crazy and set a command list that records the current value whenever the value of *word changes, and use that as $old. But half the time I'm using this, I'm actually using it through rr, so I might be going backwards.
There's no direct way to get these values in gdb; it's been a wish-list bug (with your exact case as the example...) for years.. The information is stored in the old_val field of the struct bpstats object associated with the breakpoint; but this is only used to print the old value and not exposed elsewhere.
One option might be to change gdb to expose this value via a convenience variable or via Python.
I suppose I could go crazy and set a command list that records the current value whenever the value of *word changes, and use that as $old. But half the time I'm using this, I'm actually using it through rr, so I might be going backwards.
This seems doable. Your script could check the current execution direction. The main difficulty is remembering to reset the saved value when making this watchpoint, or after disabling and then re-enabling it.
I use Stata since several years now, along with other languages like R.
Stata is great, but there is one thing that annoys me : the generate/replace behaviour, and especially the "... already defined" error.
It means that if we want to run a piece of code twice, if this piece of code contains the definition of a variable, this definition needs 2 lines :
capture drop foo
generate foo = ...
While it takes just one line in other languages such as R.
So is there another way to define variables that combines "generate" and "replace" in one command ?
I am unaware of any way to do this directly. Further, as #Roberto's comment implies, there are reasons simply issuing a generate command will not overwrite (see: replace) the contents of a variable.
To be able to do this while maintaining data integrity, you would need to issue two separate commands as your question points out (explicitly dropping the existing variable before generating the new one) - I see this as method in which Stata forces the user to be clear about his/her intentions.
It might be noted that Stata is not alone in this regard. SQL Server, for example, requires the user drop an existing table before creating a table with the same name (in the same database), does not allow multiple columns with the same name in a table, etc. and all for good reason.
However, if you are really set on being able to issue a one-liner in Stata to do what you desire, you could write a very simple program. The following should get you started:
program mkvar
version 13
syntax anything=exp [if] [in]
capture confirm variable `anything'
if !_rc {
drop `anything'
}
generate `anything' `exp' `if' `in'
end
You then would naturally save the program to mkvar.ado in a directory that Stata would find (i.e., C:\ado\personal\ on Windows. If you are unsure, type sysdir), and call it using:
mkvar newvar=expression [if] [in]
Now, I haven't tested the above code much so you may have to do a bit of de-bugging, but it has worked fine in the examples I've tried.
On a closing note, I'd advise you to exercise caution when doing this - certainly you will want to be vigilant with regard to altering your data, retain a copy of your raw data while a do file manipulates the data in memory, etc.