Prerequisites
A session with the server must be established.
Description
This example demonstrates how to read values having structured data types that are unknown at compile time. Press the button “Show Code” to display the corresponding code, and the button “Help” to show this documentation page.
Fill in a Node ID to the respective input field. Press the button “…” to open a tree view for browsing the server’s address space. When clicking the button “Read”, the value is displayed in the box at “Read Response”. Check the box in front of “Use Asynchronous Pattern” to call “BeginRead” instead of “Read”.
The example contains two variants for displaying the value. The text box only supports simple data types and structured data types without optional fields.
In the second variant, values are shown in a tree view. This more complicated example can additionally be used for unions, enumerations, and structured data types with optional fields.
Sample Code
For using SDK functionality to parse value with a (at compile time) unknown structured DataType it is necessary to create an instance of the DataTypeManager first.
m_dataTypeManager = new DataTypeManager(m_parent.Session);
Then we extract the ExtensionObject from the DataValue and pass it to the DataTypeManager
if (value.DataType !=
BuiltInType.ExtensionObject || value.ValueRank != ValueRanks.Scalar)
{
throw new Exception("Only scalar values of structured DataTypes can be displayed in this example");
}
{
throw new Exception("Only values of structured DataTypes that are not registered at the stack can be shown in this example.");
}
GenericEncodeableObject encodeable = m_dataTypeManager.ParseValue(e);
The following paragraphs only show how to print the value to a text box. See the complete example code for the more elaborate tree view.
Structures may be nested, so a recursive method is needed to show a structure’s content.
private void PrintValue(GenericEncodeableObject genericValue)
{
m_text.Text = "";
GenericStructureDataType structuredDataType = genericValue.TypeDefinition;
{
m_text.Text = structuredDataType.Name.Name;
PrintValueRec(genericValue, 1);
}
}
private void PrintValueRec(GenericEncodeableObject genericValue, int depth)
{
We get the fields of the structure and iterate over these fields.
GenericStructureDataType structuredDataType = genericValue.TypeDefinition;
for (int i = 0; i < depth; i++)
{
intend += " ";
}
for (int i = 0; i < structuredDataType.Count; i++)
{
GenericStructureDataTypeField fieldDescription = structuredDataType[i];
Variant fieldValue = genericValue[i];
string fieldName = fieldDescription.Name;
Then we have to check the TypeClass and ValueRank of each field. If a field contains a structured DataType, the recursive method is called again.
if (fieldDescription.ValueRank == -1)
{
{
string fieldValueString = fieldValue.ToString();
string outputString = "\r\n" + intend + fieldName + " = " + fieldValueString;
m_text.Text = m_text.Text += outputString;
}
{
string outputString = "\r\n" + intend + fieldName;
m_text.Text = m_text.Text += outputString;
PrintValueRec((GenericEncodeableObject)fieldValue.GetValue<GenericEncodeableObject>(null), depth + 1);
}
}
else if (fieldDescription.ValueRank == 1)
{
string outputString = "\r\n" + intend + fieldName;
m_text.Text = m_text.Text += outputString;
{
Array array = fieldValue.Value as Array;
int counter = 0;
foreach (object element in array)
{
outputString = "\r\n" + intend + " " + fieldDescription.TypeDescription.Name.Name + "[" + counter++ + "]: " + element.ToString();
m_text.Text = m_text.Text += outputString;
}
}
{
ExtensionObjectCollection extensionObjects = fieldValue.ToExtensionObjectArray();
int counter = 0;
foreach (ExtensionObject e in extensionObjects)
{
outputString = "\r\n" + intend + " " + fieldDescription.TypeDescription.Name.Name + "[" + counter++ + "]";
m_text.Text = m_text.Text += outputString;
PrintValueRec((GenericEncodeableObject)e.Body, depth + 2);
}
}
}