Files
UA-.NETStandard/docs/NodeSetExport.md
T
Copilot d525bc3f28 Bound reconnect cleanup and organize samples by domain (#4276)
# Description

This PR fixes bounded ManagedSession reconnect cleanup and reorganizes
the sample applications into domain-focused folders.

## Reconnect cleanup

- Bounds reconnect integration cleanup with independent 30-second close
and dispose limits.
- Sends `CloseSession` through the awaited transport request path during
`Session.DisposeAsync`.
- Preserves explicit `Session.CloseAsync` behavior that waits for or
cancels outstanding publish requests.
- Covers the disposal request path with a regression test.

## Sample organization

- `samples/OpenUsd`: `GeneratorServer`, `SiteCompositionServer`
- `samples/Redundancy`: `RedundantClient`, `RedundantServer`,
`RedundantPubSub`
- `samples/Isa95`: `MinimalIsa95Server`
- `samples/MinimalApi`: `MinimalBoilerServer`, `MinimalCalcServer`,
`MinimalClient`
- `samples/DI`: `PumpDeviceIntegrationServer`
- `samples/Lds`: `ConsoleLdsServer`
- `samples/Reference`: `ConsoleReferenceClient`,
`ConsoleReferenceServer`
- `samples/PubSub`: `ConsoleReferencePubSubClient`

`UA.slnx` now exposes the same requested domain groups. Project
references, tests, runtime sample probes, CI workflows, Dockerfiles,
Compose files, helper scripts, and documentation were updated to the new
paths. `samples/Robotics/MinimalRobotServer` remains under `Robotics`.

## Validation

- `dotnet build UA.slnx`
- 3 Redundancy short-haul sample tests
- 70 DI sample tests
- 914 OpenUSD tests
- 1 WotCon model-materialization test
- 137 AOT tests
- `docker compose config` for all 6 moved Redundancy Compose files

## Related Issues

- Fixes #4273

## Checklist

- [ ] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [x] I have added all necessary documentation.
- [x] I have verified that my changes do not introduce new build or
analyzer warnings.
- [x] I built the complete `UA.slnx` solution locally.
- [ ] I ran all tests locally against at least .NET Framework and .NET
10.
- [ ] I fixed all failing and flaky tests in the CI pipelines and all
CodeQL warnings.
- [x] I have addressed all PR feedback received.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
Co-authored-by: Marc Schier <mschier@microsoft.com>
Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>
Copilot-Session: a2c2838f-74ae-4997-a1d4-50574d9e0636
2026-08-21 04:35:47 +00:00

5.4 KiB

Client-based NodeSet Export

The OPC UA .NET Standard stack provides the ability to export the address space from an OPC UA server to a NodeSet2 XML file using the client library. This allows you to browse a server's address space and save it to a file that can be used for documentation, analysis, or import into other systems.

Overview

The client-based NodeSet export feature enables:

  • Browsing and collecting nodes from an OPC UA server
  • Converting client-side node representations (INode) to server-side representations (NodeState)
  • Exporting nodes to standard NodeSet2 XML format
  • Round-tripping: exported NodeSets can be imported using existing import functionality

Usage

Basic Example

using System.IO;
using Opc.Ua;
using Opc.Ua.Client;

// Connect to server and create session
var session = await Session.CreateAsync(/*...*/);

// Browse to collect nodes
var browser = new Browser(session)
{
    BrowseDirection = BrowseDirection.Forward,
    ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences,
    IncludeSubtypes = true,
    NodeClassMask = 0
};

var nodesToBrowse = new NodeIdCollection { ObjectIds.Server };
var allNodes = new List<INode>();

// Browse and collect nodes
ReferenceDescriptionCollection references = await browser.BrowseAsync(nodesToBrowse[0]);

foreach (ReferenceDescription reference in references)
{
    INode node = await session.NodeCache.FindAsync(reference.NodeId);
    if (node != null)
    {
        allNodes.Add(node);
    }
}

// Export to NodeSet2 file
using (var stream = new FileStream("exported-nodeset.xml", FileMode.Create))
{
    var systemContext = new SystemContext(telemetry)
    {
        NamespaceUris = session.NamespaceUris,
        ServerUris = session.ServerUris
    };

    CoreClientUtils.ExportNodesToNodeSet2(systemContext, allNodes, stream);
}

Using the Console Reference Client

The console reference client (ClientSamples class) includes a helper method for exporting nodes:

// Browse and collect nodes using the existing helper
IList<INode> nodes = await clientSamples.FetchAllNodesNodeCacheAsync(
    uaClient,
    ObjectIds.ObjectsFolder,  // Starting node
    fetchTree: true,           // Recursively browse the tree
    addRootNode: true,         // Include the root node
    filterUATypes: true,       // Filter out namespace 0 nodes
    clearNodeCache: true
);

// Export to NodeSet2 file
clientSamples.ExportNodesToNodeSet2(session, nodes, "address-space.xml");

Supported Node Types

The export functionality supports all standard OPC UA node types:

  • Object nodes - Objects and their properties
  • Variable nodes - Variables with their values and data types
  • Method nodes - Methods with their executable status
  • ObjectType nodes - Object type definitions
  • VariableType nodes - Variable type definitions
  • DataType nodes - Data type definitions
  • ReferenceType nodes - Reference type definitions
  • View nodes - View definitions

Features

Node Attributes Exported

For each node, the following attributes are exported (where applicable):

  • NodeId
  • BrowseName
  • DisplayName
  • Description
  • WriteMask and UserWriteMask
  • References to other nodes
  • Type-specific attributes (e.g., DataType for variables, EventNotifier for objects)

Namespace Handling

The export functionality properly handles:

  • Multiple namespaces
  • Namespace URIs are included in the exported NodeSet
  • NodeIds are correctly mapped to namespace indices

References

All references between nodes are preserved in the export, including:

  • Hierarchical references (e.g., HasComponent, HasProperty)
  • Type definition references (e.g., HasTypeDefinition)
  • Organizing references
  • Custom reference types

Limitations

  • The export creates a snapshot of the address space at the time of browsing
  • Dynamic values are captured as they exist at export time
  • Not all server-specific internal state may be preserved
  • Complex type definitions require the complex types system to be loaded

API Reference

CoreClientUtils.ExportNodesToNodeSet2

public static void ExportNodesToNodeSet2(
    ISystemContext context,
    IList<INode> nodes,
    Stream outputStream)

Parameters:

  • context - System context containing namespace and server URI information
  • nodes - List of nodes to export
  • outputStream - Stream to write the NodeSet2 XML to

Exceptions:

  • ArgumentNullException - If any parameter is null

ClientSamples.ExportNodesToNodeSet2

public void ExportNodesToNodeSet2(
    ISession session,
    IList<INode> nodes,
    string filePath)

Parameters:

  • session - Active session to use for namespace information
  • nodes - List of nodes to export
  • filePath - Path where the NodeSet2 XML file will be saved

Examples

For complete examples of using the NodeSet export functionality, see:

  • tests/Opc.Ua.Client.Tests/NodeSetExportTest.cs - Unit tests demonstrating various export scenarios
  • samples/Reference/ConsoleReferenceClient/ClientSamples.cs - Integration in the reference client

See Also