> For the complete documentation index, see [llms.txt](https://docs.zongsoft.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zongsoft.com/documentation/en/framework/core/collections/hierarchical.md).

# Hierarchical Structures

Hierarchical hierarchical nodes, node collections, path search and hierarchical expressions.

`Hierarchical` related types provide tree nodes, node collections, path search and expression parsing capabilities. Models such as `Category`, configuration tree, option tree, etc. that need to "locate nodes by path" can reuse this infrastructure.

## Type Relationship

| Type                                | Description                                                                                                      |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `HierarchicalNode`                  | Non-generic hierarchical node base class that provides name, path, full path, and illegal character constraints. |
| `HierarchicalNode<TNode>`           | Generic hierarchical node base class, providing parent node, child node collection and `Find` search logic.      |
| `HierarchicalNodeCollection<TNode>` | A collection of child nodes based on the name key, ignoring case, prohibiting adding root nodes.                 |
| `HierarchicalNodeUtility`           | Provides `IsRoot` and other hierarchical node extension methods.                                                 |
| `HierarchicalExpression`            | Represents the parsing result of "hierarchical path + member access expression".                                 |
| `HierarchicalExpressionParser`      | Parse hierarchical expression text.                                                                              |

## Hierarchy Node

Hierarchical nodes use `/` as the path separator. The root node name is `/`, `Path` of the root node is an empty string, and `FullPath` is `/`.

Source: [framework/Zongsoft.Core/test/Collections/CategoryTest.cs](https://github.com/Zongsoft/framework/blob/main/Zongsoft.Core/test/Collections/CategoryTest.cs#L11) (excerpt; see source for context).

{% code title="CategoryTest.cs" %}

```csharp
public void TestName()
{
	var root = Initialize();

	Assert.True(root.IsRoot());
	Assert.Equal("/", root.Name);
	Assert.Equal(string.Empty, root.Path);
	Assert.Equal("/", root.FullPath);

	var category = new Category();
	Assert.True(root.IsRoot());

	Assert.IsType<ArgumentException>(Record.Exception(() => root.Categories.Add(category)));
	Assert.IsType<ArgumentException>(Record.Exception(() => new Category("/")));
	Assert.IsType<ArgumentException>(Record.Exception(() => new Category("ABC\\")));
	Assert.IsType<ArgumentException>(Record.Exception(() => new Category("ABC/DEF")));
	Assert.IsType<ArgumentNullException>(Record.Exception(() => new Category(string.Empty)));
	Assert.IsType<ArgumentNullException>(Record.Exception(() => new Category(" ")));
	Assert.IsType<ArgumentNullException>(Record.Exception(() => new Category("\t")));
	Assert.IsType<ArgumentNullException>(Record.Exception(() => new Category("\n")));
	Assert.IsType<ArgumentNullException>(Record.Exception(() => new Category("\r")));
	Assert.IsType<ArgumentNullException>(Record.Exception(() => new Category(Environment.NewLine)));
}
```

{% endcode %}

The node name cannot be empty and cannot contain path separators and characters reserved for hierarchical expressions.

## Pathfinding

`HierarchicalNode<TNode>.Find` supports the following path forms:

| path         | Description                                               |
| ------------ | --------------------------------------------------------- |
| `/A/B`       | Start searching from the root node.                       |
| `A/B`        | Start searching from the child nodes of the current node. |
| `./A`        | Start searching from the current node.                    |
| `../A`       | Start searching from the parent node.                     |
| empty string | Return the current node.                                  |

For the complete creation and search process, see [Real test examples for Category](/documentation/en/framework/core/collections/category.md#path-lookup), where the same File / Edit / Help classification tree is reused.

Whitespace at both ends of path segments is ignored. Returns `null` when the node is not found.

## Hierarchical Expression

`HierarchicalExpression` is used to parse "node path + member accessor". The expression consists of two parts: path and optional member access.

Source: [framework/Zongsoft.Core/test/Collections/HierarchicalExpressionTest.cs](https://github.com/Zongsoft/framework/blob/main/Zongsoft.Core/test/Collections/HierarchicalExpressionTest.cs#L16) (excerpt; see source for context).

{% code title="HierarchicalExpressionTest.cs" %}

```csharp
var TEXT = @"/";
var expression = HierarchicalExpressionParser.Parse(TEXT);

Assert.NotNull(expression);
Assert.Null(expression.Accessor);
Assert.Equal(PathAnchor.Root, expression.Anchor);
Assert.Equal("/", expression.Path);
Assert.True(expression.Segments == null || expression.Segments.Length == 0);
```

{% endcode %}

Common formats include:

* `/root/node@property`
* `../sibling/node@property`
* `child/node[index]`
* `@property1.property2`

Member access is partially parsed by `Zongsoft.Reflection.Expressions`, so property, indexer, and chained member access can be expressed.

## Related Resources

* [HierarchicalExpression.cs](https://github.com/Zongsoft/framework/blob/main/Zongsoft.Core/src/Collections/HierarchicalExpression.cs)
* [HierarchicalExpressionParser.cs](https://github.com/Zongsoft/framework/blob/main/Zongsoft.Core/src/Collections/HierarchicalExpressionParser.cs)
* [HierarchicalNode.cs](https://github.com/Zongsoft/framework/blob/main/Zongsoft.Core/src/Collections/HierarchicalNode.cs)
* [HierarchicalNode\<T>.cs](https://github.com/Zongsoft/framework/blob/main/Zongsoft.Core/src/Collections/HierarchicalNode%601.cs)
* [HierarchicalNodeCollection.cs](https://github.com/Zongsoft/framework/blob/main/Zongsoft.Core/src/Collections/HierarchicalNodeCollection.cs)
* [HierarchicalNodeUtility.cs](https://github.com/Zongsoft/framework/blob/main/Zongsoft.Core/src/Collections/HierarchicalNodeUtility.cs)
* [HierarchicalExpressionTest.cs](https://github.com/Zongsoft/framework/blob/main/Zongsoft.Core/test/Collections/HierarchicalExpressionTest.cs)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.zongsoft.com/documentation/en/framework/core/collections/hierarchical.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
