Hierarchy Code Examples

Note

🔧 Intermediate / Architecture — Practical code examples for working with element hierarchies.

Example 1: Three-Level Process Hierarchy

Create a simple three-level hierarchy of business processes:

from pyArchimate import Model, ArchiType

model = Model(name="Order Processing Hierarchy")

# Level 1: Top-level process
order_mgmt = model.add_element(
    name="Order Management",
    element_type=ArchiType.BusinessProcess
)

# Level 2: Sub-processes
receive_order = model.add_element(
    name="Receive Order",
    element_type=ArchiType.BusinessProcess
)
validate_order = model.add_element(
    name="Validate Order",
    element_type=ArchiType.BusinessProcess
)
fulfill_order = model.add_element(
    name="Fulfill Order",
    element_type=ArchiType.BusinessProcess
)

# Create parent-child relationships (level 2)
model.add_child(parent=order_mgmt, child=receive_order)
model.add_child(parent=order_mgmt, child=validate_order)
model.add_child(parent=order_mgmt, child=fulfill_order)

# Level 3: Sub-sub-processes
check_payment = model.add_element(
    name="Check Payment",
    element_type=ArchiType.BusinessProcess
)
check_stock = model.add_element(
    name="Check Stock",
    element_type=ArchiType.BusinessProcess
)

# Create parent-child relationships (level 3)
model.add_child(parent=validate_order, child=check_payment)
model.add_child(parent=validate_order, child=check_stock)

# Verify structure
print(f"Order Management has {len(order_mgmt.get_children())} direct children")
print(f"Order Management has {len(order_mgmt.get_descendants())} total descendants")
print(f"Validate Order has depth {validate_order.get_depth()}")

# Save the model
model.write("order_hierarchy.archimate")

Example 2: Path Wildcard Queries

Find elements using hierarchy path patterns with wildcards:

from pyArchimate import Model, ArchiType

model = Model(name="Service Architecture")

# Create a multi-level service hierarchy
payment_service = model.add_element(
    name="Payment Service",
    element_type=ArchiType.ApplicationService
)

payment_processing = model.add_element(
    name="Payment Processing",
    element_type=ArchiType.ApplicationService
)
fraud_check = model.add_element(
    name="Fraud Check",
    element_type=ArchiType.ApplicationService
)

model.add_child(parent=payment_service, child=payment_processing)
model.add_child(parent=payment_service, child=fraud_check)

# Level 3
auth = model.add_element(
    name="Authorization",
    element_type=ArchiType.ApplicationService
)
capture = model.add_element(
    name="Capture",
    element_type=ArchiType.ApplicationService
)

model.add_child(parent=payment_processing, child=auth)
model.add_child(parent=payment_processing, child=capture)

# Query examples
# Find all direct children of Payment Service
results = model.find_by_hierarchy_path("Payment Service/*")
print(f"Direct children: {[e.name for e in results]}")

# Find all descendants matching a pattern
results = model.find_by_hierarchy_path("Payment Service/*/Auth*")
print(f"Authorization descendants: {[e.name for e in results]}")

# Find all at a specific depth
results = model.find_by_hierarchy_path("*/Processing/*")
print(f"Depth 2 descendants: {[e.name for e in results]}")

Example 3: Walking a Subtree

Recursively traverse a hierarchy to process all descendants:

from pyArchimate import Model, ArchiType

model = Model(name="Organization Structure")

# Create an organizational hierarchy
company = model.add_element(
    name="Company",
    element_type=ArchiType.BusinessActor
)

engineering = model.add_element(
    name="Engineering",
    element_type=ArchiType.BusinessActor
)
backend = model.add_element(
    name="Backend Team",
    element_type=ArchiType.BusinessActor
)

model.add_child(parent=company, child=engineering)
model.add_child(parent=engineering, child=backend)

def print_hierarchy(element, indent=0):
    """Recursively print element hierarchy."""
    print("  " * indent + f"- {element.name}")
    for child in element.get_children():
        print_hierarchy(child, indent + 1)

# Print the entire organizational hierarchy
print_hierarchy(company)

# Calculate total span of control
def count_all_descendants(element):
    """Count all descendants including self."""
    total = 1
    for child in element.get_children():
        total += count_all_descendants(child)
    return total

span = count_all_descendants(company)
print(f"Total organizational units: {span}")

Example 4: Detecting Cycles

Implement cycle detection to ensure hierarchies are acyclic (no circular references):

from pyArchimate import Model, ArchiType

model = Model(name="Acyclic Hierarchy Check")

# Create some elements
a = model.add_element(name="A", element_type=ArchiType.BusinessProcess)
b = model.add_element(name="B", element_type=ArchiType.BusinessProcess)
c = model.add_element(name="C", element_type=ArchiType.BusinessProcess)

# Create a valid hierarchy
model.add_child(parent=a, child=b)
model.add_child(parent=b, child=c)

def has_cycle(element, visited=None, rec_stack=None):
    """Check if adding a relationship would create a cycle."""
    if visited is None:
        visited = set()
    if rec_stack is None:
        rec_stack = set()

    visited.add(element.id)
    rec_stack.add(element.id)

    for child in element.get_children():
        if child.id not in visited:
            if has_cycle(child, visited, rec_stack):
                return True
        elif child.id in rec_stack:
            return True

    rec_stack.remove(element.id)
    return False

# Check for cycles
print(f"Hierarchy has cycle: {has_cycle(a)}")

# Try to detect if we could add a reverse relationship (which would create a cycle)
def can_add_relationship(parent, child):
    """Check if adding parent->child relationship is safe."""
    # Check if child is already an ancestor of parent
    ancestors = parent.get_ancestors()
    return child not in ancestors

print(f"Can add C->A? {can_add_relationship(c, a)}")  # False (would create cycle)
print(f"Can add C->B? {can_add_relationship(c, b)}")  # False (would create cycle)

# Add a safe new element
d = model.add_element(name="D", element_type=ArchiType.BusinessProcess)
print(f"Can add D as child of C? {can_add_relationship(d, c)}")  # True (safe)