UA_NodeId from XML string

110 views
Skip to first unread message

pth...@caltech.edu

unread,
Oct 3, 2017, 12:51:06 PM10/3/17
to open62541
Hi,

I was wondering if there is an existing function to create a UA_NodeId from an XML string representing a fully qualified NodeId as defined by the OPC UA XML Schema (ns=<namespaceIndex>;<identifiertype>=<identifier>) and vice versa.

For reference: http://documentation.unified-automation.com/uasdkhp/1.0.0/html/_l2_ua_node_ids.html

Thank you for your time,
Patrick

Julius Pfrommer

unread,
Oct 3, 2017, 5:18:28 PM10/3/17
to open62541
Hey Patrick,

there is no NodeId parsing built into open62541.
But I have some code that evolved across a range of projects.
The listing is attached below.

If somebody asks, I am the author and hereby release it under the CC0 license.
So you can do whatever, but there is no warranty.

#include <stdio.h>
#include "open62541.h"

static UA_StatusCode
parseGuid(char *sid, UA_Guid *guid) {
    if(strlen(sid) != 36) {
        UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
                    "Guid needs to be of the form \"00000000-0000-0000-0000-000000000000\"");
        return UA_STATUSCODE_BADINTERNALERROR;
    }
    guid->data1 = strtoull(sid, NULL, 16);
    guid->data2 = strtoull(&sid[9], NULL, 16);
    guid->data3 = strtoull(&sid[14], NULL, 16);
    UA_Int16 data4_1 = strtoull(&sid[19], NULL, 16);
    guid->data4[0] = data4_1 >> 8;
    guid->data4[1] = data4_1;
    UA_Int64 data4_2 = strtoull(&sid[24], NULL, 16);
    guid->data4[2] = data4_2 >> 40;
    guid->data4[3] = data4_2 >> 32;
    guid->data4[4] = data4_2 >> 24;
    guid->data4[5] = data4_2 >> 16;
    guid->data4[6] = data4_2 >> 8;
    guid->data4[7] = data4_2;
    return UA_STATUSCODE_GOOD;
}

/* Parse NodeId from String */
static UA_StatusCode
parseNodeId(UA_String str, UA_NodeId *id) {
    /* force zero-termination of the string */
    char *s = (char *) alloca(str.length + 1);
    memcpy(s, str.data, str.length);
    s[str.length] = 0;

    UA_NodeId_init(id);

    /* Int identifier */
    if(sscanf(s, "ns=%hu;i=%u", &id->namespaceIndex, &id->identifier.numeric) == 2 ||
       sscanf(s, "ns=%hu,i=%u", &id->namespaceIndex, &id->identifier.numeric) == 2 ||
       sscanf(s, "i=%u", &id->identifier.numeric) == 1) {
        id->identifierType = UA_NODEIDTYPE_NUMERIC;
        return UA_STATUSCODE_GOOD;
    }

    /* String identifier */
    char *sid = alloca(str.length);
    if(sscanf(s, "ns=%hu;s=%[^\n]", &id->namespaceIndex, sid) == 2 ||
       sscanf(s, "ns=%hu,s=%[^\n]", &id->namespaceIndex, sid) == 2 ||
       sscanf(s, "s=%s", sid) == 1) {
        id->identifierType = UA_NODEIDTYPE_STRING;
        id->identifier.string = UA_String_fromChars(sid);
        return UA_STATUSCODE_GOOD;
    }

    /* ByteString idenifier */
    if(sscanf(s, "ns=%hu;b=%[^\n]", &id->namespaceIndex, sid) == 2 ||
       sscanf(s, "ns=%hu,b=%[^\n]", &id->namespaceIndex, sid) == 2 ||
       sscanf(s, "b=%s", sid) == 1) {
        id->identifierType = UA_NODEIDTYPE_BYTESTRING;
        id->identifier.string = UA_String_fromChars(sid);
        return UA_STATUSCODE_GOOD;
    }

    /* Guid idenifier */
    if(sscanf(s, "ns=%hu;g=%s", &id->namespaceIndex, sid) == 2 ||
       sscanf(s, "ns=%hu,g=%s", &id->namespaceIndex, sid) == 2 ||
       sscanf(s, "g=%s", sid) == 1) {
        UA_StatusCode retval = parseGuid(sid, &id->identifier.guid);
        if(retval != UA_STATUSCODE_GOOD)
            return retval;
        id->identifierType = UA_NODEIDTYPE_GUID;
        return UA_STATUSCODE_GOOD;
    }

    return UA_STATUSCODE_BADINTERNALERROR;
}


Best regards,
Julius

pth...@caltech.edu

unread,
Oct 3, 2017, 5:34:58 PM10/3/17
to open62541
Thank you!

-Patrick

Grüner, Sten

unread,
Oct 3, 2017, 5:46:17 PM10/3/17
to Julius Pfrommer, open62541
Can the code go into the repo?
--
You received this message because you are subscribed to the Google Groups "open62541" group.
To unsubscribe from this group and stop receiving emails from it, send an email to open62541+...@googlegroups.com.
To post to this group, send email to open...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/open62541/15a444e0-2722-4f4d-8944-6d20d9edcfc9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Julius Pfrommer

unread,
Oct 3, 2017, 5:51:11 PM10/3/17
to open62541
Where do you suggest it should go?


Am Dienstag, 3. Oktober 2017 23:46:17 UTC+2 schrieb Grüner, Sten:
Can the code go into the repo?
Reply all
Reply to author
Forward
0 new messages