QuickOPC User's Guide and Reference
BrowseNodes Method (IEasyDAClient)
Example 



OpcLabs.EasyOpcClassic Assembly > OpcLabs.EasyOpc.DataAccess Namespace > IEasyDAClient Interface : BrowseNodes Method
The OPC server involved in the operation.
Descriptor for the parent branch to be browsed (can be the root).
Contains filtering conditions.
Browses the specified branch (or root) in OPC server's address space, and returns information about child nodes (both branches and leaves) found. Specify server descriptor, parent item ID, and node filter.
Syntax
'Declaration
 
<ElementsNotNullAttribute()>
<NotNullAttribute()>
Function BrowseNodes( _
   ByVal serverDescriptor As ServerDescriptor, _
   ByVal parentNodeDescriptor As DANodeDescriptor, _
   ByVal browseParameters As DABrowseParameters _
) As DANodeElementCollection
'Usage
 
Dim instance As IEasyDAClient
Dim serverDescriptor As ServerDescriptor
Dim parentNodeDescriptor As DANodeDescriptor
Dim browseParameters As DABrowseParameters
Dim value As DANodeElementCollection
 
value = instance.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)

Parameters

serverDescriptor
The OPC server involved in the operation.
parentNodeDescriptor
Descriptor for the parent branch to be browsed (can be the root).
browseParameters
Contains filtering conditions.

Return Value

The method returns a keyed collection of OpcLabs.EasyOpc.DataAccess.AddressSpace.DANodeElement values, each containing information about a particular node found. The keys of the keyed collection are the names of the nodes.
Exceptions
ExceptionDescription
Thrown when the OPC operation fails.
A null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.
Example
// This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
// whether the node is a branch or a leaf.

using System;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class BrowseNodes
    {
        public static void Main1()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            DANodeElementCollection nodeElements;
            try
            {
                nodeElements = client.BrowseNodes("", "OPCLabs.KitServer.2", "Greenhouse", DABrowseParameters.Default);
            }
            catch (OpcException opcException)
            {
                Console.WriteLine($"*** Failure: {opcException.GetBaseException().Message}");
                return;
            }

            foreach (DANodeElement nodeElement in nodeElements)
            {
                Console.WriteLine($"NodeElements(\"{nodeElement.Name}\"):");
                Console.WriteLine($"    .IsBranch: {nodeElement.IsBranch}");
                Console.WriteLine($"    .IsLeaf: {nodeElement.IsLeaf}");
            }
        }
    }
}
# This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
# whether the node is a branch or a leaf.

#requires -Version 5.1
using namespace OpcLabs.EasyOpc.OperationModel
using namespace OpcLabs.EasyOpc.DataAccess

# The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows .
Add-Type -Path "../../../Assemblies/net47/OpcLabs.EasyOpcClassic.dll"

# Instantiate the client object.
$client = New-Object EasyDAClient

try {
    $nodeElements = [IEasyDAClientExtension]::BrowseNodes($client,
        "", "OPCLabs.KitServer.2", "Greenhouse", [DABrowseParameters]::Default)
}
catch [OpcException] {
    Write-Host "*** Failure: $($PSItem.Exception.GetBaseException().Message)"
    return
}

Foreach ($nodeElement in $nodeElements) {
    Write-Host "NodeElements(`"$($nodeElement.Name)`"):"
    Write-Host "    .IsBranch: $($nodeElement.IsBranch)"
    Write-Host "    .IsLeaf: $($nodeElement.IsLeaf)"
}
// This example shows how to obtain data types of leaves in the OPC-DA address 
// space by browsing and filtering, i.e. without the use of OPC properties. 
// This technique allows determining the data types with servers that only 
// support OPC-DA 1.0. It can also be more effective than the use of 
// GetMultiplePropertyValues, if there is large number of leaves, and 
// relatively small number of data types to be checked.

using System;
using System.Collections.Generic;
using OpcLabs.BaseLib.ComInterop;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class BrowseNodes
    {
        public static void DataTypes()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            // Define the list of data types we will be checking for. 
            // Change as needed for your application.
            // This technique is only usable if there is a known list of 
            // data types you are interested in. If you are interested in 
            // all leaves, even those that are of data types not explicitly 
            // listed, always include VarTypes.Empty as the first data type. 
            // The leaves of "unlisted" data types will have VarTypes.Empty 
            // associated with them.
            var dataTypes = new VarType[] { VarTypes.Empty, VarTypes.I2, VarTypes.R4 };

            // For each leaf found, this dictionary wil hold its associated data type.
            var dataTypeDictionary = new Dictionary<DANodeElement, VarType>();

            // For each data type, browse for leaves of this data type.
            foreach (VarType dataType in dataTypes)
            {
                var browseParameters = new DABrowseParameters(DABrowseFilter.Leaves, "", "", dataType);
                DANodeElementCollection nodeElements;
                try
                {
                    nodeElements = client.BrowseNodes("", "OPCLabs.KitServer.2", "Greenhouse", browseParameters);
                }
                catch (OpcException opcException)
                {
                    Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                    return;
                }

                // Store the leaf information into the dictionary, and 
                // associate the current data type with it.
                foreach (var nodeElement in nodeElements)
                    dataTypeDictionary[nodeElement] = dataType;
            }

            // Display each leaf found, and its associated data type.
            foreach (KeyValuePair<DANodeElement, VarType> pair in dataTypeDictionary)
            {
                DANodeElement nodeElement = pair.Key;
                VarType dataType = pair.Value;
                Console.WriteLine("{0}: {1}", nodeElement, dataType);
            }
        }
    }
}
' This example shows how to obtain data types of leaves in the OPC-DA address 
' space by browsing and filtering, i.e. without the use of OPC properties. 
' This technique allows determining the data types with servers that only 
' support OPC-DA 1.0. It can also be more effective than the use of 
' GetMultiplePropertyValues, if there is large number of leaves, and 
' relatively small number of data types to be checked.

Imports OpcLabs.BaseLib.ComInterop
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DocExamples.DataAccess._EasyDAClient
    Partial Friend Class BrowseNodes
        Shared Sub DataTypes()
            Dim client = New EasyDAClient()

            ' Define the list of data types we will be checking for. 
            ' Change as needed for your application.
            ' This technique is only usable if there is a known list of 
            ' data types you are interested in. If you are interested in 
            ' all leaves, even those that are of data types not explicitly 
            ' listed, always include VarTypes.Empty as the first data type. 
            ' The leaves of "unlisted" data types will have VarTypes.Empty 
            ' associated with them.
            Dim dataTypes() = New VarType() {VarTypes.Empty, VarTypes.I2, VarTypes.R4}

            ' For each leaf found, this dictionary wil hold its associated data type.
            Dim dataTypeDictionary = New Dictionary(Of DANodeElement, VarType)()

            ' For each data type, browse for leaves of this data type.
            For Each dataType As VarType In dataTypes
                Dim browseParameters = New DABrowseParameters(DABrowseFilter.Leaves, "", "", dataType)
                Dim nodeElements As DANodeElementCollection
                Try
                    nodeElements = client.BrowseNodes("", "OPCLabs.KitServer.2", "Greenhouse", browseParameters)
                Catch opcException As OpcException
                    Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                    Exit Sub
                End Try

                ' Store the leaf information into the dictionary, and 
                ' associate the current data type with it.
                For Each nodeElement In nodeElements
                    dataTypeDictionary(nodeElement) = dataType
                Next nodeElement
            Next dataType

            For Each pair In dataTypeDictionary
                Dim nodeElement As DANodeElement = pair.Key
                Dim dataType As VarType = pair.Value
                Console.WriteLine("{0}: {1}", nodeElement, dataType)
            Next pair
        End Sub
    End Class
End Namespace
// This example shows how to recursively browse the nodes in the OPC address space.

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class BrowseNodes
    {
        public static void Recursive()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            // Instantiate the client object.
            var client = new EasyDAClient();
            _branchCount = 0;
            _leafCount = 0;

            try
            {
                BrowseFromNode(client, "OPCLabs.KitServer.2", "");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            stopwatch.Stop();
            Console.WriteLine("Browsing has taken (milliseconds): {0}", stopwatch.ElapsedMilliseconds);
            Console.WriteLine("Branch count: {0}", _branchCount);
            Console.WriteLine("Leaf count: {0}", _leafCount);
        }

        private static void BrowseFromNode(
            EasyDAClient client,
            ServerDescriptor serverDescriptor,
            DANodeDescriptor parentNodeDescriptor)
        {
            Debug.Assert(client != null);
            Debug.Assert(serverDescriptor != null);
            Debug.Assert(parentNodeDescriptor != null);

            // Obtain all node elements under parentNodeDescriptor
            var browseParameters = new DABrowseParameters();    // no filtering whatsoever
            DANodeElementCollection nodeElementCollection =
                client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters);
            // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
            // it, here omitted for brevity.

            foreach (DANodeElement nodeElement in nodeElementCollection)
            {
                Debug.Assert(nodeElement != null);

                Console.WriteLine(nodeElement);

                // If the node is a branch, browse recursively into it.
                if (nodeElement.IsBranch)
                {
                    _branchCount++;
                    BrowseFromNode(client, serverDescriptor, nodeElement);
                }
                else
                {
                    _leafCount++;
                }
            }
        }

        private static int _branchCount;
        private static int _leafCount;
    }
}
' This example shows how to recursively browse the nodes in the OPC address space.

Imports OpcLabs.EasyOpc
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DocExamples.DataAccess._EasyDAClient
    Partial Friend Class BrowseNodes

        Shared Sub Recursive()
            Dim stopwatch = New Stopwatch()
            stopwatch.Start()

            Dim client = New EasyDAClient()
            _branchCount = 0
            _leafCount = 0

            Try
                BrowseFromNode(client, "OPCLabs.KitServer.2", "")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try

            stopwatch.Stop()
            Console.WriteLine("Browsing has taken (milliseconds): {0}", stopwatch.ElapsedMilliseconds)
            Console.WriteLine("Branch count: {0}", _branchCount)
            Console.WriteLine("Leaf count: {0}", _leafCount)
        End Sub

        Private Shared Sub BrowseFromNode( _
            client As EasyDAClient,
            serverDescriptor As ServerDescriptor,
            parentNodeDescriptor As DANodeDescriptor)

            Debug.Assert(client IsNot Nothing)
            Debug.Assert(serverDescriptor IsNot Nothing)
            Debug.Assert(parentNodeDescriptor IsNot Nothing)

            ' Obtain all node elements under parentNodeDescriptor
            Dim browseParameters = New DABrowseParameters() ' no filtering whatsoever
            Dim nodeElementCollection As DANodeElementCollection =
                client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)
            ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
            ' it, here omitted for brevity.

            For Each nodeElement As DANodeElement In nodeElementCollection
                Debug.Assert(nodeElement IsNot Nothing)

                Console.WriteLine(nodeElement)

                ' If the node is a branch, browse recursively into it.
                If nodeElement.IsBranch Then
                    _branchCount += 1
                    BrowseFromNode(client, serverDescriptor, nodeElement)
                Else
                    _leafCount += 1
                End If
            Next nodeElement
        End Sub

        Private Shared _branchCount As Integer
        Private Shared _leafCount As Integer
    End Class
End Namespace
// Recursively browses and displays the nodes in the OPC address space, and attempts to read and display values of all OPC 
// items it finds.

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class BrowseNodes
    {
        const string ServerClass = "OPCLabs.KitServer.2";

        // Instantiate the client object.
        static readonly EasyDAClient Client = new EasyDAClient();

        static void BrowseAndReadFromNode(string parentItemId)
        {
            // Obtain all node elements under parentItemId
            var browseParameters = new DABrowseParameters(); // no filtering whatsoever
            DANodeElementCollection nodeElementCollection = Client.BrowseNodes("", ServerClass, parentItemId,
                browseParameters);
            // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for it, here 
            // omitted for brevity.

            foreach (DANodeElement nodeElement in nodeElementCollection)
            {
                Debug.Assert(nodeElement != null);

                // If the node is a leaf, it might be possible to read from it
                if (nodeElement.IsLeaf)
                {
                    // Determine what the display - either the value read, or exception message in case of failure.
                    string display;
                    try
                    {
                        object value = Client.ReadItemValue("", ServerClass, nodeElement);
                        display = $"{value}";
                    }
                    catch (OpcException exception)
                    {
                        display = $"** {exception.GetBaseException().Message} **";
                    }

                    Console.WriteLine("{0} -> {1}", nodeElement.ItemId, display);
                }
                // If the node is not a leaf, just display its itemId
                else
                    Console.WriteLine("{0}", nodeElement.ItemId);

                // If the node is a branch, browse recursively into it.
                if (nodeElement.IsBranch &&
                    (nodeElement.ItemId != "SimulateEvents")
                    /* this branch is too big for the purpose of this example */)
                    BrowseAndReadFromNode(nodeElement);
            }
        }

        public static void RecursiveWithRead()
        {
            Console.WriteLine("Browsing and reading values...");
            // Set timeout to only wait 1 second - default would be 1 minute to wait for good quality that may never come.
            Client.InstanceParameters.Timeouts.ReadItem = 1000;

            // Do the actual browsing and reading, starting from root of OPC address space (denoted by empty string for itemId)
            try
            {
                BrowseAndReadFromNode("");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
            }
        }
    }
}
' Recursively browses and displays the nodes in the OPC address space, and attempts to read and display values of all OPC 
' items it finds.

Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DocExamples.DataAccess._EasyDAClient
    Partial Friend Class BrowseNodes
        Private Const ServerClass As String = "OPCLabs.KitServer.2"

        Private Shared ReadOnly Client As New EasyDAClient()

        Private Shared Sub BrowseAndReadFromNode(parentItemId As String)
            ' Obtain all node elements under parentItemId
            Dim browseParameters = New DABrowseParameters() ' no filtering whatsoever
            Dim nodeElementCollection As DANodeElementCollection = Client.BrowseNodes("", ServerClass, parentItemId, browseParameters)
            ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for it, here 
            ' omitted for brevity.

            For Each nodeElement As DANodeElement In nodeElementCollection
                Debug.Assert(nodeElement IsNot Nothing)

                ' If the node is a leaf, it might be possible to read from it
                If nodeElement.IsLeaf Then
                    ' Determine what the display - either the value read, or exception message in case of failure.
                    Dim display As String
                    Try
                        Dim value As Object = Client.ReadItemValue("", ServerClass, nodeElement.ItemId)
                        display = String.Format("{0}", value)
                    Catch exception As OpcException
                        display = String.Format("** {0} **", exception.GetBaseException().Message)
                    End Try

                    Console.WriteLine("{0} -> {1}", nodeElement.ItemId, display)
                    ' If the node is not a leaf, just display its itemId
                Else
                    Console.WriteLine("{0}", nodeElement.ItemId)
                End If

                ' If the node is a branch, browse recursively into it.
                If nodeElement.IsBranch AndAlso (nodeElement.ItemId <> "SimulateEvents") Then ' this branch is too big for the purpose of this example
                    BrowseAndReadFromNode(nodeElement.ItemId)
                End If
            Next nodeElement
        End Sub

        Shared Sub RecursiveWithRead()
            Console.WriteLine("Browsing and reading values...")
            ' Set timeout to only wait 1 second - default would be 1 minute to wait for good quality that may never come.
            Client.InstanceParameters.Timeouts.ReadItem = 1000

            ' Do the actual browsing and reading, starting from root of OPC address space (denoted by empty string for itemId)
            Try
                BrowseAndReadFromNode("")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try
        End Sub
    End Class
End Namespace
' Recursively browses and displays the nodes in the OPC address space, and attempts to read and display values of all OPC 
' items it finds.

Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DocExamples.DataAccess._EasyDAClient
    Partial Friend Class BrowseNodes
        Private Const ServerClass As String = "OPCLabs.KitServer.2"

        Private Shared ReadOnly Client As New EasyDAClient()

        Private Shared Sub BrowseAndReadFromNode(parentItemId As String)
            ' Obtain all node elements under parentItemId
            Dim browseParameters = New DABrowseParameters() ' no filtering whatsoever
            Dim nodeElementCollection As DANodeElementCollection = Client.BrowseNodes("", ServerClass, parentItemId, browseParameters)
            ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for it, here 
            ' omitted for brevity.

            For Each nodeElement As DANodeElement In nodeElementCollection
                Debug.Assert(nodeElement IsNot Nothing)

                ' If the node is a leaf, it might be possible to read from it
                If nodeElement.IsLeaf Then
                    ' Determine what the display - either the value read, or exception message in case of failure.
                    Dim display As String
                    Try
                        Dim value As Object = Client.ReadItemValue("", ServerClass, nodeElement.ItemId)
                        display = String.Format("{0}", value)
                    Catch exception As OpcException
                        display = String.Format("** {0} **", exception.GetBaseException().Message)
                    End Try

                    Console.WriteLine("{0} -> {1}", nodeElement.ItemId, display)
                    ' If the node is not a leaf, just display its itemId
                Else
                    Console.WriteLine("{0}", nodeElement.ItemId)
                End If

                ' If the node is a branch, browse recursively into it.
                If nodeElement.IsBranch AndAlso (nodeElement.ItemId <> "SimulateEvents") Then ' this branch is too big for the purpose of this example
                    BrowseAndReadFromNode(nodeElement.ItemId)
                End If
            Next nodeElement
        End Sub

        Shared Sub RecursiveWithRead()
            Console.WriteLine("Browsing and reading values...")
            ' Set timeout to only wait 1 second - default would be 1 minute to wait for good quality that may never come.
            Client.InstanceParameters.Timeouts.ReadItem = 1000

            ' Do the actual browsing and reading, starting from root of OPC address space (denoted by empty string for itemId)
            Try
                BrowseAndReadFromNode("")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try
        End Sub
    End Class
End Namespace
// This example shows how to recursively browse the nodes in the OPC XML-DA address space.

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess.Xml
{
    class BrowseNodes
    {
        public static void RecursiveXml()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            // Instantiate the client object.
            var client = new EasyDAClient();

            _branchCount = 0;
            _leafCount = 0;

            try
            {
                BrowseFromNode(client, "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx", "");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            stopwatch.Stop();
            Console.WriteLine("Browsing has taken (milliseconds): {0}", stopwatch.ElapsedMilliseconds);
            Console.WriteLine("Branch count: {0}", _branchCount);
            Console.WriteLine("Leaf count: {0}", _leafCount);
        }

        private static void BrowseFromNode(
            EasyDAClient client,
            ServerDescriptor serverDescriptor,
            DANodeDescriptor parentNodeDescriptor)
        {
            Debug.Assert(client != null);
            Debug.Assert(serverDescriptor != null);
            Debug.Assert(parentNodeDescriptor != null);

            // Obtain all node elements under parentNodeDescriptor
            var browseParameters = new DABrowseParameters();    // no filtering whatsoever
            DANodeElementCollection nodeElementCollection =
                client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters);
            // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
            // it, here omitted for brevity.

            foreach (DANodeElement nodeElement in nodeElementCollection)
            {
                Debug.Assert(nodeElement != null);

                Console.WriteLine(nodeElement);

                // If the node is a branch, browse recursively into it.
                if (nodeElement.IsBranch)
                {
                    _branchCount++;
                    BrowseFromNode(client, serverDescriptor, nodeElement);
                }
                else
                {
                    _leafCount++;
                }
            }
        }

        private static int _branchCount;
        private static int _leafCount;
    }
}
' This example shows how to recursively browse the nodes in the OPC XML-DA address space.

Imports OpcLabs.EasyOpc
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DocExamples.DataAccess.Xml
    Partial Friend Class BrowseNodes

        Shared Sub RecursiveXml()
            Dim stopwatch = New Stopwatch()
            stopwatch.Start()

            Dim client = New EasyDAClient()
            _branchCount = 0
            _leafCount = 0

            Try
                BrowseFromNode(client, "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx", "")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try

            stopwatch.Stop()
            Console.WriteLine("Browsing has taken (milliseconds): {0}", stopwatch.ElapsedMilliseconds)
            Console.WriteLine("Branch count: {0}", _branchCount)
            Console.WriteLine("Leaf count: {0}", _leafCount)
        End Sub

        Private Shared Sub BrowseFromNode( _
            client As EasyDAClient,
            serverDescriptor As ServerDescriptor,
            parentNodeDescriptor As DANodeDescriptor)

            Debug.Assert(client IsNot Nothing)
            Debug.Assert(serverDescriptor IsNot Nothing)
            Debug.Assert(parentNodeDescriptor IsNot Nothing)

            ' Obtain all node elements under parentNodeDescriptor
            Dim browseParameters = New DABrowseParameters() ' no filtering whatsoever
            Dim nodeElementCollection As DANodeElementCollection =
                client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)
            ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
            ' it, here omitted for brevity.

            For Each nodeElement As DANodeElement In nodeElementCollection
                Debug.Assert(nodeElement IsNot Nothing)

                Console.WriteLine(nodeElement)

                ' If the node is a branch, browse recursively into it.
                If nodeElement.IsBranch Then
                    _branchCount += 1
                    BrowseFromNode(client, serverDescriptor, nodeElement)
                Else
                    _leafCount += 1
                End If
            Next nodeElement
        End Sub

        Private Shared _branchCount As Integer
        Private Shared _leafCount As Integer
    End Class
End Namespace
Requirements

Target Platforms: .NET Framework: Windows 10 (selected versions), Windows 11 (selected versions), Windows Server 2012, Windows Server 2016; .NET Core, .NET 5, .NET 6: Linux, macOS, Microsoft Windows

See Also

Reference

IEasyDAClient Interface
IEasyDAClient Members