// This example shows how to recursively browse the nodes in the OPC XML-DA address space.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.
type
  TBrowseNodes = class
    BranchCount: Integer;
    LeafCount: Integer;
    procedure BrowseFromNode(
      Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
      ServerDescriptor: _ServerDescriptor;
      ParentNodeDescriptor:  _DANodeDescriptor);
  end;
procedure TBrowseNodes.BrowseFromNode(
      Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
      ServerDescriptor: _ServerDescriptor;
      ParentNodeDescriptor: _DANodeDescriptor);
var
  BrowseParameters: _DABrowseParameters;
  Count: Cardinal;
  Element: OleVariant;
  NodeElement: _DANodeElement;
  NodeElementEnumerator: IEnumVariant;
  NodeElements: _DANodeElementCollection;
begin
  // Obtain all node elements under ParentNodeDescriptor
  BrowseParameters := CoDABrowseParameters.Create;  // no filtering whatsover
  NodeElements := Client.BrowseNodes(
    ServerDescriptor,
    ParentNodeDescriptor,
    BrowseParameters);
  // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
  // it, here omitted for brevity.
  NodeElementEnumerator := NodeElements.GetEnumerator;
  while (NodeElementEnumerator.Next(1, Element, Count) = S_OK) do
  begin
    NodeElement := IUnknown(Element) as _DANodeElement;
    WriteLn(NodeElement.ToString);
    // If the node is a branch, browse recursively into it.
    if NodeElement.IsBranch then
    begin
      BranchCount := BranchCount + 1;
      BrowseFromNode(Client, ServerDescriptor, NodeElement.ToDANodeDescriptor);
    end
    else
      LeafCount := LeafCount + 1;
  end;
end;
class procedure BrowseNodes.RecursiveXml;
var
  BeginTime: Cardinal;
  BrowseNodes: TBrowseNodes;
  Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
  EndTime: Cardinal;
  ServerDescriptor: _ServerDescriptor;
  NodeDescriptor: _DANodeDescriptor;
begin
  BrowseNodes := TBrowseNodes.Create;
  BrowseNodes.BranchCount := 0;
  BrowseNodes.LeafCount := 0;
  BeginTime := Ticks;
  ServerDescriptor := CoServerDescriptor.Create;
  ServerDescriptor.UrlString := 'http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx';
  NodeDescriptor := CoDANodeDescriptor.Create;
  NodeDescriptor.ItemId := '';
  // Instantiate the client object
  Client := CoEasyDAClient.Create;
  try
    BrowseNodes.BrowseFromNode(
      Client,
      ServerDescriptor,
      NodeDescriptor);
  except
    on E: EOleException do
    begin
      WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      Exit;
    end;
  end;
  EndTime := Ticks;
  WriteLn;
  WriteLn('Browsing has taken (milliseconds): ', (endTime - beginTime) * 1000);
  WriteLn('Branch count: ', BrowseNodes.BranchCount);
  WriteLn('Leaf count: ', BrowseNodes.LeafCount);
end;
	 
	
		// This example shows how to recursively browse the nodes in the OPC XML-DA address space.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in PHP on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PHP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.
$beginTime = microtime(true);
$branchCount = 0;
$leafCount = 0;
$ServerDescriptor = new COM("OpcLabs.EasyOpc.ServerDescriptor");
$ServerDescriptor->UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx";
$NodeDescriptor = new COM("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor");
$NodeDescriptor->ItemID = "";
// Instantiate the client object.
$Client = new COM("OpcLabs.EasyOpc.DataAccess.EasyDAClient");
try
{
    BrowseFromNode($Client, $ServerDescriptor, $NodeDescriptor);
}
catch (com_exception $e)
{
    printf("*** Failure: %s\n", $e->getMessage());
    Exit();
}
$endTime = microtime(true);
printf("\n");
printf("Browsing has taken (milliseconds): : %f\n", ($endTime - $beginTime) * 1000);
printf("Branch count: %d\n", $branchCount);
printf("Leaf count: %d\n", $leafCount);
function BrowseFromNode($Client, $ServerDescriptor, $ParentNodeDescriptor) : void
{
    global $branchCount, $leafCount;
    // Obtain all node elements under ParentNodeDescriptor
    $BrowseParameters = new COM("OpcLabs.EasyOpc.DataAccess.DABrowseParameters"); // no filtering whatsoever
    $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 ($NodeElementCollection as $NodeElement)
    {
        printf("%s\n", $NodeElement);
        // If the node is a branch, browse recursively into it.
        if ($NodeElement->IsBranch)
        {
            $branchCount = $branchCount + 1;
            BrowseFromNode($Client, $ServerDescriptor, $NodeElement->ToDANodeDescriptor());
        }
        else
        {
            $leafCount = $leafCount + 1;
        }
    }
}
	 
	
		Rem This example shows how to recursively browse the nodes in the OPC XML-DA address space.
Rem
REM Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
REM OPC client and subscriber examples in Visual Basic on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VB .
REM Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
REM a commercial license in order to use Online Forums, and we reply to every post.
'Public branchCount As Integer
'Public leafCount As Integer
Private Sub BrowseNodes_RecursiveXml_Command_Click()
    OutputText = ""
    branchCount = 0
    leafCount = 0
    Dim beginTime: beginTime = Timer
        
    Dim serverDescriptor As New serverDescriptor
    serverDescriptor.UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"
    
    Dim NodeDescriptor As New DANodeDescriptor
    NodeDescriptor.ItemId = ""
    
    ' Instantiate the client object
    Dim client As New EasyDAClient
    On Error Resume Next
        BrowseFromNode client, serverDescriptor, NodeDescriptor
    If Err.Number <> 0 Then
        OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
        Exit Sub
    End If
    On Error GoTo 0
    Dim endTime: endTime = Timer
    
    OutputText = OutputText & vbCrLf
    OutputText = OutputText & "Browsing has taken (milliseconds): " & (endTime - beginTime) * 1000 & vbCrLf
    OutputText = OutputText & "Branch count: " & branchCount & vbCrLf
    OutputText = OutputText & "Leaf count: " & leafCount & vbCrLf
End Sub
Public Sub BrowseFromNode(client, serverDescriptor, ParentNodeDescriptor)
    ' Obtain all node elements under ParentNodeDescriptor
    Dim BrowseParameters As New DABrowseParameters
    Dim NodeElementCollection As DANodeElementCollection
    Set 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.
    Dim NodeElement: For Each NodeElement In NodeElementCollection
        OutputText = OutputText & NodeElement & vbCrLf
        
        ' If the node is a branch, browse recursively into it.
        If NodeElement.IsBranch Then
            branchCount = branchCount + 1
            BrowseFromNode client, serverDescriptor, NodeElement.ToDANodeDescriptor
        Else
            leafCount = leafCount + 1
        End If
    Next
End Sub
	 
	
		Rem This example shows how to recursively browse the nodes in the OPC XML-DA address space.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.
Option Explicit
Dim beginTime: beginTime = Timer
Dim branchCount: branchCount = 0
Dim leafCount: leafCount = 0
Dim ServerDescriptor: Set ServerDescriptor = CreateObject("OpcLabs.EasyOpc.ServerDescriptor")
ServerDescriptor.UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"
Dim NodeDescriptor: Set NodeDescriptor = CreateObject("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor")
NodeDescriptor.ItemID = ""
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
On Error Resume Next
BrowseFromNode Client, ServerDescriptor, NodeDescriptor
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0
Dim endTime: endTime = Timer
WScript.Echo ""
WScript.Echo "Browsing has taken (milliseconds): " & (endTime - beginTime) * 1000
WScript.Echo "Branch count: " & branchCount
WScript.Echo "Leaf count: " & leafCount
Sub BrowseFromNode(Client, ServerDescriptor, ParentNodeDescriptor)
    ' Obtain all node elements under ParentNodeDescriptor
    Dim BrowseParameters: Set BrowseParameters = CreateObject("OpcLabs.EasyOpc.DataAccess.DABrowseParameters")
    Dim NodeElementCollection: Set 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.
    Dim NodeElement: For Each NodeElement In NodeElementCollection
        WScript.Echo NodeElement
        
        ' If the node is a branch, browse recursively into it.
        If NodeElement.IsBranch Then
            branchCount = branchCount + 1
            BrowseFromNode Client, ServerDescriptor, NodeElement.ToDANodeDescriptor
        Else
            leafCount = leafCount + 1
        End If
    Next
End Sub