Reputation: 2728
I am new to stuctured text and I would like to know how to concatenate several string. The cleanest way possible. I this instance I only need to change one variable when creating the string. I have another where I need to do 2. That number will probably grow. The purpose of this is so I can send XML message to an HTTP server. This is for logging data.
In this instance it is the reader variable which is a word.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService/receiveHeartbeat</Action>
</s:Header>
<s:Body>
<receiveHeartbeat xmlns="http://tempuri.org/">
<reader>**Word Variable**</reader>
</receiveHeartbeat>
</s:Body>
</s:Envelope>
Upvotes: 3
Views: 13699
Reputation: 1
now we can use stu.StrConcatA to work with string more than 255 charactors
FUNCTION StrConcatA : BOOL
This function concatenates |pstFrom| to |pstTo| if the |iBufferSize| from |pstTo| is big enough. The function will do its work either with native IEC-Strings or with strings coming from external functions.
Upvotes: 0
Reputation: 1064
// Concatenates from 2 to 9 strings. Unused input vars can be omitted.
FUNCTION CONCAT9 : STRING(255)
VAR_INPUT
str1: STRING;
str2: STRING;
str3: STRING := '';
str4: STRING := '';
str5: STRING := '';
str6: STRING := '';
str7: STRING := '';
str8: STRING := '';
str9: STRING := '';
END_VAR
CONCAT9 := CONCAT(str1, str2);
IF (LEN(str3) = 0) THEN RETURN; END_IF
CONCAT9 := CONCAT(CONCAT9, str3);
IF (LEN(str4) = 0) THEN RETURN; END_IF
CONCAT9 := CONCAT(CONCAT9, str4);
IF (LEN(str5) = 0) THEN RETURN; END_IF
CONCAT9 := CONCAT(CONCAT9, str5);
IF (LEN(str6) = 0) THEN RETURN; END_IF
CONCAT9 := CONCAT(CONCAT9, str6);
IF (LEN(str7) = 0) THEN RETURN; END_IF
CONCAT9 := CONCAT(CONCAT9, str7);
IF (LEN(str8) = 0) THEN RETURN; END_IF
CONCAT9 := CONCAT(CONCAT9, str8);
IF (LEN(str9) = 0) THEN RETURN; END_IF
CONCAT9 := CONCAT(CONCAT9, str9);
Length checks allow to exit earlier without making unnecessary CONCAT operations.
Upvotes: 1
Reputation: 1734
You can chain CONCAT
functions like so:
concat3: STRING := CONCAT(CONCAT(str1, str2), str3);
However, beware that by default STRING
is only 80 characters (81 bytes) long.
If a size is not defined, then CODESYS allocates 80 characters by default.
You can specify the size using parenthesis:
concat3: STRING(255) := CONCAT(CONCAT(str1, str2), str3);
But again, the standard CONCAT
function (and others) only accepts and returns strings of up to 255 in length!
If you need strings longer than 255, then check Working with Strings More Than 255 Characters in the codesys documentation.
If you often work with strings, it might be useful to create your own Concat3
, Concat4
, etc.. functions for future use.
If your codesys version supports default values for function inputs, and you don't mind wasting a few CPU cycles, you may do something like this:
FUNCTION StringConcat : STRING(255)
VAR_INPUT
STR1: STRING(255);
STR2: STRING(255);
STR3: STRING(255):= '';
STR4: STRING(255):= '';
// etc up to a large number
END_VAR
StringConcat := CONCAT(STR1 := StringConcat, STR2 := STR1);
StringConcat := CONCAT(STR1 := StringConcat, STR2 := STR2);
StringConcat := CONCAT(STR1 := StringConcat, STR2 := STR3);
StringConcat := CONCAT(STR1 := StringConcat, STR2 := STR4);
// etc up to all defined inputs
With the function above, you can use the same function to concatenate as many strings as you want (well, up to the number of inputs you defined), for example:
str1: STRING(255);
str2: STRING(255);
// implementation:
str1 := StringConcat('Hello', ' ', 'World', '!');
str2 := StringConcat('Hell', 'o', ' ', 'World', '!', '!', '!');
Result:
Although, beware that using StringConcat
during declaration produces garbage (seems to be a bug in codesys with default values in the declaration), for example:
str1: STRING(255) := StringConcat('Hello', ' ', 'World', '!');
Results is:
Upvotes: 5
Reputation: 67
If you are using Wago then you should have access to their CONCAT functions...CONCAT3(),CONCAT4()...CONCAT9(). This is much cleaner than nesting a lot of the standard CONCAT funct
Upvotes: 2
Reputation: 2728
I think I have found a solution. I don't like it though. It's not very clean.
Reader_ID: STRING := '0';
msg: STRING(500);
Msg1: STRING(250) := '<s:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><s:Header>';
Msg2: STRING(250) := '<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService/receiveHeartbeat</Action>';
Msg3: STRING := '</s:Header><s:Body><receiveHeartbeat xmlns="http://tempuri.org/"><reader>';
MsgAfter: STRING := '</reader></receiveHeartbeat></s:Body></s:Envelope>';
msg := CONCAT(Msg1,Msg2);
msg := CONCAT(msg,Msg3);
msg := CONCAT(msg,Reader_ID);
msg := CONCAT(msg,MsgAfter);
It seems that string sizes are limited to 500 characters. Since the point of this is to create an XML message to send via HTTP. What happens when my messages inevitably get larger than 500 character. I am using the WagoLibHttp_02 library for http.
Upvotes: 0
Reputation: 11
I take it that you need to do this in JavaScript.
var replaceDue = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\
<s:Header>\
<Action s:mustUnderstand=\"1\"xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">http://tempuri.org/IService/receiveHeartbeat</Action>\
</s:Header>\
<s:Body>\
<receiveHeartbeat xmlns=\"http://tempuri.org/\">\
<reader>**Word Variable**</reader>\
</receiveHeartbeat>\
</s:Body>\
</s:Envelope>";
var wordVariable = "value to replace";
var replaceDone = replaceDue.replace("**Word Variable**", wordVariable);
Upvotes: 0